[virt-tools-list] [PATCH virt-viewer] Connecting without specifying VM domain name

Pavel Grunt pgrunt at redhat.com
Mon Sep 29 09:02:41 UTC 2014


When user starts virt-viewer without specifying VM domain name
or with a wrong name a list of running machines is shown
and user may choose one of them.
---
Depends on http://www.redhat.com/archives/virt-tools-list/2014-September/msg00253.html

 src/virt-viewer-main.c |   4 +-
 src/virt-viewer.c      | 118 +++++++++++++++++++++++++++++++++++++++++++------
 2 files changed, 106 insertions(+), 16 deletions(-)

diff --git a/src/virt-viewer-main.c b/src/virt-viewer-main.c
index 44d1182..3fae955 100644
--- a/src/virt-viewer-main.c
+++ b/src/virt-viewer-main.c
@@ -104,12 +104,12 @@ int main(int argc, char **argv)
 
     g_option_context_free(context);
 
-    if (!args || (g_strv_length(args) != 1)) {
+    if (args && (g_strv_length(args) != 1)) {
         g_printerr(_("\nUsage: %s [OPTIONS] DOMAIN-NAME|ID|UUID\n\n%s\n\n"), argv[0], help_msg);
         goto cleanup;
     }
 
-    viewer = virt_viewer_new(uri, args[0], direct, attach, waitvm, reconnect);
+    viewer = virt_viewer_new(uri, (args) ? args[0] : NULL, direct, attach, waitvm, reconnect);
     if (viewer == NULL)
         goto cleanup;
 
diff --git a/src/virt-viewer.c b/src/virt-viewer.c
index c6066c5..f19163d 100644
--- a/src/virt-viewer.c
+++ b/src/virt-viewer.c
@@ -526,6 +526,87 @@ virt_viewer_dispose (GObject *object)
     G_OBJECT_CLASS(virt_viewer_parent_class)->dispose (object);
 }
 
+static void
+treeview_row_activated_cb(GtkTreeView *treeview G_GNUC_UNUSED,
+                          GtkTreePath *path G_GNUC_UNUSED,
+                          GtkTreeViewColumn *col G_GNUC_UNUSED,
+                          gpointer userdata)
+{
+    gtk_widget_activate(GTK_WIDGET(userdata));
+}
+
+static void
+treeselection_changed_cb(GtkTreeSelection *selection, gpointer userdata)
+{
+    gtk_widget_set_sensitive(GTK_WIDGET(userdata),
+                             gtk_tree_selection_count_selected_rows(selection) == 1);
+}
+
+static virDomainPtr
+choose_vm_dialog(char **vm_name, virConnectPtr conn, GError **error)
+{
+    GtkBuilder *vm_connection;
+    GtkWidget *dialog;
+    GtkButton *button_connect;
+    GtkTreeView *treeview;
+    GtkTreeModel *store;
+    GtkTreeSelection *select;
+    GtkTreeIter iter;
+    virDomainPtr *domains, dom = NULL;
+    int i, vms_running, response;
+    unsigned int flags = VIR_CONNECT_LIST_DOMAINS_RUNNING;
+
+    g_return_val_if_fail(vm_name != NULL, NULL);
+    if (*vm_name != NULL) {
+        free(*vm_name);
+    }
+
+    vm_connection = virt_viewer_util_load_ui("virt-viewer-vm-connection.xml");
+    dialog = GTK_WIDGET(gtk_builder_get_object(vm_connection, "vm-connection-dialog"));
+    button_connect = GTK_BUTTON(gtk_builder_get_object(vm_connection, "button-connect"));
+    treeview = GTK_TREE_VIEW(gtk_builder_get_object(vm_connection, "treeview"));
+    select = GTK_TREE_SELECTION(gtk_builder_get_object(vm_connection, "treeview-selection"));
+    store = GTK_TREE_MODEL(gtk_builder_get_object(vm_connection, "store"));
+
+    g_signal_connect(treeview, "row-activated",
+        G_CALLBACK(treeview_row_activated_cb), button_connect);
+    g_signal_connect(select, "changed",
+        G_CALLBACK(treeselection_changed_cb), button_connect);
+
+    vms_running = virConnectListAllDomains(conn, &domains, flags);
+    for (i = 0; i < vms_running; i++) {
+        gtk_list_store_append(GTK_LIST_STORE(store), &iter);
+        gtk_list_store_set(GTK_LIST_STORE(store), &iter, 0, virDomainGetName(domains[i]), -1);
+        virDomainFree(domains[i]);
+    }
+    free(domains);
+
+    if (vms_running > 0) {
+        gtk_widget_show_all(dialog);
+        response = gtk_dialog_run(GTK_DIALOG(dialog));
+        gtk_widget_hide(dialog);
+        if (response == GTK_RESPONSE_ACCEPT &&
+            gtk_tree_selection_get_selected(select, &store, &iter)) {
+            gtk_tree_model_get(store, &iter, 0, vm_name, -1);
+            dom = virDomainLookupByName(conn, *vm_name);
+        } else {
+            g_set_error_literal(error,
+                                VIRT_VIEWER_ERROR, VIRT_VIEWER_VM_CHOOSE_DIALOG_CANCELLED,
+                                _("No virtual machine was chosen"));
+        }
+    } else {
+        char *uri = virConnectGetURI(conn);
+        g_set_error(error,
+                    VIRT_VIEWER_ERROR, VIRT_VIEWER_ERROR_FAILED,
+                   _("No running virtual machines found on %s"), uri);
+        free(uri);
+    }
+    gtk_widget_destroy(dialog);
+    g_object_unref(G_OBJECT(vm_connection));
+
+    return dom;
+}
+
 static int virt_viewer_connect(VirtViewerApp *app);
 
 static gboolean
@@ -537,6 +618,7 @@ virt_viewer_initial_connect(VirtViewerApp *app, GError **error)
     VirtViewer *self = VIRT_VIEWER(app);
     VirtViewerPrivate *priv = self->priv;
     char uuid_string[VIR_UUID_STRING_BUFLEN];
+    GError *err = NULL;
 
     g_debug("initial connect");
 
@@ -547,19 +629,22 @@ virt_viewer_initial_connect(VirtViewerApp *app, GError **error)
     }
 
     virt_viewer_app_show_status(app, _("Finding guest domain"));
-    dom = virt_viewer_lookup_domain(self);
-    if (!dom) {
-        if (priv->waitvm) {
-            virt_viewer_app_show_status(app, _("Waiting for guest domain to be created"));
-            virt_viewer_app_trace(app, "Guest %s does not yet exist, waiting for it to be created",
-                                  priv->domkey);
-            goto done;
-        } else {
-            virt_viewer_app_simple_message_dialog(app, _("Cannot find guest domain %s"),
-                                                  priv->domkey);
-            g_debug("Cannot find guest %s", priv->domkey);
+
+    if (priv->domkey == NULL ||
+        ((dom = virt_viewer_lookup_domain(self)) == NULL && !priv->waitvm)) {
+        dom = choose_vm_dialog(&priv->domkey, priv->conn, &err);
+        if (dom == NULL) {
+            if (err != NULL &&
+                !g_error_matches(err, VIRT_VIEWER_ERROR, VIRT_VIEWER_VM_CHOOSE_DIALOG_CANCELLED)) {
+                virt_viewer_app_simple_message_dialog(app, err->message);
+            }
             goto cleanup;
         }
+    } else if (!dom && priv->waitvm) {
+        virt_viewer_app_show_status(app, _("Waiting for guest domain to be created"));
+        virt_viewer_app_trace(app, "Guest %s does not yet exist, waiting for it to be created",
+                              priv->domkey);
+        goto done;
     }
 
     if (virDomainGetUUIDString(dom, uuid_string) < 0) {
@@ -579,14 +664,16 @@ virt_viewer_initial_connect(VirtViewerApp *app, GError **error)
     } else {
         ret = virt_viewer_update_display(self, dom);
         if (ret)
-            ret = VIRT_VIEWER_APP_CLASS(virt_viewer_parent_class)->initial_connect(app, error);
+            ret = VIRT_VIEWER_APP_CLASS(virt_viewer_parent_class)->initial_connect(app, &err);
         if (!ret) {
             if (priv->waitvm) {
                 virt_viewer_app_show_status(app, _("Waiting for guest domain to start server"));
                 virt_viewer_app_trace(app, "Guest %s has not activated its display yet, waiting for it to start",
                                       priv->domkey);
             } else {
-                g_debug("Failed to activate viewer");
+                g_set_error_literal(&err, VIRT_VIEWER_ERROR, VIRT_VIEWER_ERROR_FAILED,
+                                    _("Failed to activate viewer"));
+                g_debug(err->message);
                 goto cleanup;
             }
         }
@@ -595,6 +682,8 @@ virt_viewer_initial_connect(VirtViewerApp *app, GError **error)
  done:
     ret = TRUE;
  cleanup:
+    if (err != NULL)
+        g_propagate_error(error, err);
     if (dom)
         virDomainFree(dom);
     return ret;
@@ -739,7 +828,8 @@ virt_viewer_connect(VirtViewerApp *app)
     }
 
     if (!virt_viewer_app_initial_connect(app, &error)) {
-        if (error)
+        if (error &&
+            !g_error_matches(error, VIRT_VIEWER_ERROR, VIRT_VIEWER_VM_CHOOSE_DIALOG_CANCELLED))
             g_warning("%s", error->message);
         g_clear_error(&error);
         return -1;
-- 
1.9.3




More information about the virt-tools-list mailing list