[virt-tools-list] [virt-viewer 6/7] Implement ovirt_foreign_menu_new_from_file()
Jonathon Jongsma
jjongsma at redhat.com
Thu Apr 17 15:09:18 UTC 2014
----- Original Message -----
> From: "Christophe Fergeau" <cfergeau at redhat.com>
> To: virt-tools-list at redhat.com
> Sent: Wednesday, April 16, 2014 11:59:53 AM
> Subject: [virt-tools-list] [virt-viewer 6/7] Implement ovirt_foreign_menu_new_from_file()
>
> This will create an OvirtForeignMenu instance from a .vv file. Contrary to
> the ovirt:// case when we already have an OvirtAPI and OvirtVm instance,
> when working from a .vv file, we'll need to get them from the REST API.
> Authentication should happen through the JSESSIONID cookie, if that fails
> we want to give up on using the foreign menu, so we don't need to set up
> authentication callbacks.
> ---
> src/ovirt-foreign-menu.c | 174
> +++++++++++++++++++++++++++++++++++++++++++++++
> src/ovirt-foreign-menu.h | 2 +
> 2 files changed, 176 insertions(+)
>
> diff --git a/src/ovirt-foreign-menu.c b/src/ovirt-foreign-menu.c
> index 642c0ef..57ffd60 100644
> --- a/src/ovirt-foreign-menu.c
> +++ b/src/ovirt-foreign-menu.c
> @@ -25,6 +25,8 @@
>
> #include <config.h>
>
> +#include <string.h>
> +
> #include "ovirt-foreign-menu.h"
> #include "virt-glib-compat.h"
>
> @@ -35,12 +37,16 @@
>
> typedef enum {
> STATE_0,
> + STATE_API,
> + STATE_VM,
> STATE_STORAGE_DOMAIN,
> STATE_VM_CDROM,
> STATE_ISOS
> } 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 gboolean ovirt_foreign_menu_refresh_iso_list(gpointer user_data);
> @@ -52,11 +58,13 @@ struct _OvirtForeignMenuPrivate {
> OvirtProxy *proxy;
> OvirtApi *api;
> OvirtVm *vm;
> + char *vm_guid;
>
> OvirtCollection *files;
> OvirtCdrom *cdrom;
>
> GList *iso_names;
> +
> };
>
>
> @@ -69,6 +77,7 @@ enum {
> PROP_API,
> PROP_VM,
> PROP_FILES,
> + PROP_VM_GUID,
> };
>
> static void
> @@ -90,6 +99,10 @@ ovirt_foreign_menu_get_property(GObject *object, guint
> property_id,
> break;
> case PROP_FILES:
> g_value_set_pointer(value, priv->iso_names);
> + break;
Looks like there was a missing break here before? I guess it's not a huge deal, since you'll just get an extraneous invalid property warning when you get the 'files' property, but it might be worth fixing that in the patch 2 where you introduced this class.
> + case PROP_VM_GUID:
> + g_value_set_string(value, priv->vm_guid);
> + break;
>
> default:
> G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
> @@ -122,6 +135,15 @@ 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:
> + g_free(priv->vm_guid);
> + priv->vm_guid = g_value_dup_string(value);
Is it valid to set the vm-guid property when priv->vm is non-null? Should we issue a warning if priv->vm is already set?
> break;
> default:
> G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
> @@ -150,6 +172,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;
> @@ -212,6 +237,14 @@ 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_READABLE |
> +
> G_PARAM_STATIC_STRINGS));
> }
>
>
> @@ -236,6 +269,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);
> @@ -530,6 +579,88 @@ 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;
> + GList *vms;
> + GList *it;
> +
> + 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;
> + }
> +
> + vms =
> g_hash_table_get_values(ovirt_collection_get_resources(collection));
GHashTableIter?
> + for (it = vms; it != NULL; it = it->next) {
> + char *guid;
> +
> + g_object_get(G_OBJECT(it), "guid", &guid, NULL);
'it' is GList*, I assume you want it->data (assuming you don't change to GHashTableIter...)
> + if (g_strcmp0(guid, menu->priv->vm_guid) == 0) {
> + menu->priv->vm = g_object_ref(it);
same issue here. Also, I assume you can simply break out of the loop here after you find the matching GUID?
> + }
> + }
> + g_list_free(vms);
> + if (menu->priv->vm != NULL) {
> + ovirt_foreign_menu_next_async_step(menu, STATE_VM);
> + } else {
> + g_debug("failed to find a VM with guid \"%s\"",
> menu->priv->vm_guid);
warning?
> + }
> +}
> +
> +
> +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)
> @@ -578,3 +709,46 @@ 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 = ovirt_foreign_menu_new(proxy);
> + g_object_set(G_OBJECT(menu), "guid", vm_guid, NULL);
> +end:
> + g_free(url);
> + g_free(vm_guid);
> + g_free(jsessionid);
> + g_free(ca_str);
'ca' byte array is leaked?
> +
> + return menu;
> +}
> diff --git a/src/ovirt-foreign-menu.h b/src/ovirt-foreign-menu.h
> index ffadd46..4ba77a3 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);
> --
> 1.9.0
>
> _______________________________________________
> virt-tools-list mailing list
> virt-tools-list at redhat.com
> https://www.redhat.com/mailman/listinfo/virt-tools-list
>
More information about the virt-tools-list
mailing list