summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ovirt-foreign-menu.c186
-rw-r--r--src/ovirt-foreign-menu.h2
-rw-r--r--src/remote-viewer.c9
3 files changed, 197 insertions, 0 deletions
diff --git a/src/ovirt-foreign-menu.c b/src/ovirt-foreign-menu.c
index 0453ca1..6fc9577 100644
--- a/src/ovirt-foreign-menu.c
+++ b/src/ovirt-foreign-menu.c
@@ -25,12 +25,16 @@
#include <config.h>
+#include <string.h>
+
#include "ovirt-foreign-menu.h"
#include "virt-glib-compat.h"
#include "virt-viewer-util.h"
typedef enum {
STATE_0,
+ STATE_API,
+ STATE_VM,
STATE_STORAGE_DOMAIN,
STATE_VM_CDROM,
STATE_CDROM_FILE,
@@ -38,6 +42,8 @@ typedef enum {
} OvirtForeignMenuState;
static void ovirt_foreign_menu_next_async_step(OvirtForeignMenu *menu, OvirtForeignMenuState state);
+static void ovirt_foreign_menu_fetch_api_async(OvirtForeignMenu *menu);
+static void ovirt_foreign_menu_fetch_vm_async(OvirtForeignMenu *menu);
static void ovirt_foreign_menu_fetch_storage_domain_async(OvirtForeignMenu *menu);
static void ovirt_foreign_menu_fetch_vm_cdrom_async(OvirtForeignMenu *menu);
static void ovirt_foreign_menu_refresh_cdrom_file_async(OvirtForeignMenu *menu);
@@ -50,6 +56,7 @@ struct _OvirtForeignMenuPrivate {
OvirtProxy *proxy;
OvirtApi *api;
OvirtVm *vm;
+ char *vm_guid;
OvirtCollection *files;
OvirtCdrom *cdrom;
@@ -75,6 +82,7 @@ enum {
PROP_VM,
PROP_FILE,
PROP_FILES,
+ PROP_VM_GUID,
};
@@ -117,6 +125,10 @@ ovirt_foreign_menu_get_property(GObject *object, guint property_id,
case PROP_FILES:
g_value_set_pointer(value, priv->iso_names);
break;
+ case PROP_VM_GUID:
+ g_value_set_string(value, priv->vm_guid);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
@@ -148,6 +160,19 @@ ovirt_foreign_menu_set_property(GObject *object, guint property_id,
g_object_unref(priv->vm);
}
priv->vm = g_value_dup_object(value);
+ g_free(priv->vm_guid);
+ priv->vm_guid = NULL;
+ if (priv->vm != NULL) {
+ g_object_get(G_OBJECT(priv->vm), "guid", &priv->vm_guid, NULL);
+ }
+ break;
+ case PROP_VM_GUID:
+ if (priv->vm != NULL) {
+ g_object_unref(priv->vm);
+ priv->vm = NULL;
+ }
+ g_free(priv->vm_guid);
+ priv->vm_guid = g_value_dup_string(value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -175,6 +200,9 @@ ovirt_foreign_menu_dispose(GObject *obj)
self->priv->vm = NULL;
}
+ g_free(self->priv->vm_guid);
+ self->priv->vm_guid = NULL;
+
if (self->priv->files) {
g_object_unref(self->priv->files);
self->priv->files = NULL;
@@ -251,6 +279,15 @@ ovirt_foreign_menu_class_init(OvirtForeignMenuClass *klass)
"GSList of ISO names for this oVirt VM",
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property(oclass,
+ PROP_VM_GUID,
+ g_param_spec_string("vm-guid",
+ "VM GUID",
+ "GUID of the virtual machine to provide a foreign menu for",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
}
@@ -278,6 +315,22 @@ ovirt_foreign_menu_next_async_step(OvirtForeignMenu *menu,
current_state++;
+ if (current_state == STATE_API) {
+ if (menu->priv->api == NULL) {
+ ovirt_foreign_menu_fetch_api_async(menu);
+ } else {
+ current_state++;
+ }
+ }
+
+ if (current_state == STATE_VM) {
+ if (menu->priv->vm == NULL) {
+ ovirt_foreign_menu_fetch_vm_async(menu);
+ } else {
+ current_state++;
+ }
+ }
+
if (current_state == STATE_STORAGE_DOMAIN) {
if (menu->priv->files == NULL) {
ovirt_foreign_menu_fetch_storage_domain_async(menu);
@@ -635,6 +688,90 @@ static void ovirt_foreign_menu_fetch_storage_domain_async(OvirtForeignMenu *menu
}
+static void vms_fetched_cb(GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GError *error = NULL;
+ OvirtForeignMenu *menu = OVIRT_FOREIGN_MENU(user_data);
+ OvirtCollection *collection;
+ GHashTableIter iter;
+ OvirtVm *vm;
+
+ collection = OVIRT_COLLECTION(source_object);
+ ovirt_collection_fetch_finish(collection, result, &error);
+ if (error != NULL) {
+ g_debug("failed to fetch VM list: %s", error->message);
+ g_clear_error(&error);
+ return;
+ }
+
+ g_hash_table_iter_init(&iter, ovirt_collection_get_resources(collection));
+ while (g_hash_table_iter_next(&iter, NULL, (gpointer *)&vm)) {
+ char *guid;
+
+ g_object_get(G_OBJECT(vm), "guid", &guid, NULL);
+ if (g_strcmp0(guid, menu->priv->vm_guid) == 0) {
+ menu->priv->vm = g_object_ref(vm);
+ g_free(guid);
+ break;
+ }
+ g_free(guid);
+ }
+ if (menu->priv->vm != NULL) {
+ ovirt_foreign_menu_next_async_step(menu, STATE_VM);
+ } else {
+ g_warning("failed to find a VM with guid \"%s\"", menu->priv->vm_guid);
+ }
+}
+
+
+static void ovirt_foreign_menu_fetch_vm_async(OvirtForeignMenu *menu)
+{
+ OvirtCollection *vms;
+
+ g_return_if_fail(OVIRT_IS_FOREIGN_MENU(menu));
+ g_return_if_fail(OVIRT_IS_PROXY(menu->priv->proxy));
+ g_return_if_fail(OVIRT_IS_API(menu->priv->api));
+
+ vms = ovirt_api_get_vms(menu->priv->api);
+ ovirt_collection_fetch_async(vms, menu->priv->proxy,
+ NULL, vms_fetched_cb, menu);
+}
+
+
+static void api_fetched_cb(GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GError *error = NULL;
+ OvirtProxy *proxy;
+ OvirtForeignMenu *menu = OVIRT_FOREIGN_MENU(user_data);
+
+ proxy = OVIRT_PROXY(source_object);
+ menu->priv->api = ovirt_proxy_fetch_api_finish(proxy, result, &error);
+ if (error != NULL) {
+ g_debug("failed to fetch toplevel API object: %s", error->message);
+ g_clear_error(&error);
+ return;
+ }
+ g_return_if_fail(OVIRT_IS_API(menu->priv->api));
+
+ ovirt_foreign_menu_next_async_step(menu, STATE_API);
+}
+
+
+static void ovirt_foreign_menu_fetch_api_async(OvirtForeignMenu *menu)
+{
+ g_debug("Start fetching oVirt main entry point");
+
+ g_return_if_fail(OVIRT_IS_FOREIGN_MENU(menu));
+ g_return_if_fail(OVIRT_IS_PROXY(menu->priv->proxy));
+
+ ovirt_proxy_fetch_api_async(menu->priv->proxy, NULL, api_fetched_cb, menu);
+}
+
+
static void iso_list_fetched_cb(GObject *source_object,
GAsyncResult *result,
gpointer user_data)
@@ -684,3 +821,52 @@ static gboolean ovirt_foreign_menu_refresh_iso_list(gpointer user_data)
*/
return G_SOURCE_REMOVE;
}
+
+
+OvirtForeignMenu *ovirt_foreign_menu_new_from_file(VirtViewerFile *file)
+{
+ OvirtProxy *proxy = NULL;
+ OvirtForeignMenu *menu = NULL;
+ char *ca_str = NULL;
+ char *jsessionid = NULL;
+ char *url = NULL;
+ char *vm_guid = NULL;
+ GByteArray *ca = NULL;
+
+ url = virt_viewer_file_get_ovirt_host(file);
+ vm_guid = virt_viewer_file_get_ovirt_vm_guid(file);
+ jsessionid = virt_viewer_file_get_ovirt_jsessionid(file);
+ ca_str = virt_viewer_file_get_ovirt_ca(file);
+
+ if ((url == NULL) || (vm_guid == NULL))
+ goto end;
+
+ proxy = ovirt_proxy_new(url);
+ if (proxy == NULL)
+ goto end;
+
+ if (ca_str != NULL) {
+ ca = g_byte_array_new_take((guint8 *)ca_str, strlen(ca_str) + 1);
+ ca_str = NULL;
+ }
+
+ g_object_set(G_OBJECT(proxy),
+ "session-id", jsessionid,
+ "ca-cert", ca,
+ NULL);
+ menu = g_object_new(OVIRT_TYPE_FOREIGN_MENU,
+ "proxy", proxy,
+ "vm-guid", vm_guid,
+ NULL);
+
+end:
+ g_free(url);
+ g_free(vm_guid);
+ g_free(jsessionid);
+ g_free(ca_str);
+ if (ca != NULL) {
+ g_byte_array_unref(ca);
+ }
+
+ return menu;
+}
diff --git a/src/ovirt-foreign-menu.h b/src/ovirt-foreign-menu.h
index 7d28f0b..cf18b52 100644
--- a/src/ovirt-foreign-menu.h
+++ b/src/ovirt-foreign-menu.h
@@ -29,6 +29,7 @@
#include <govirt/govirt.h>
#include <gtk/gtk.h>
+#include "virt-viewer-file.h"
G_BEGIN_DECLS
@@ -66,6 +67,7 @@ struct _OvirtForeignMenuClass {
GType ovirt_foreign_menu_get_type(void);
OvirtForeignMenu* ovirt_foreign_menu_new(OvirtProxy *proxy);
+OvirtForeignMenu *ovirt_foreign_menu_new_from_file(VirtViewerFile *self);
void ovirt_foreign_menu_start(OvirtForeignMenu *menu);
GtkWidget *ovirt_foreign_menu_get_gtk_menu(OvirtForeignMenu *foreign_menu);
diff --git a/src/remote-viewer.c b/src/remote-viewer.c
index 9539b93..1e1a575 100644
--- a/src/remote-viewer.c
+++ b/src/remote-viewer.c
@@ -1171,6 +1171,15 @@ retry_dialog:
}
virt_viewer_session_set_file(virt_viewer_app_get_session(app), vvfile);
+#ifdef HAVE_OVIRT
+ if (vvfile != NULL) {
+ OvirtForeignMenu *ovirt_menu;
+ ovirt_menu = ovirt_foreign_menu_new_from_file(vvfile);
+ if (ovirt_menu != NULL) {
+ virt_viewer_app_set_ovirt_foreign_menu(app, ovirt_menu);
+ }
+ }
+#endif
if (!virt_viewer_app_initial_connect(app, &error)) {
const gchar *msg = error ? error->message :