[virt-tools-list] [virt-viewer 6/7] Implement ovirt_foreign_menu_new_from_file()

Christophe Fergeau cfergeau at redhat.com
Fri Apr 18 14:51:48 UTC 2014


Hey,

----- Mail original -----
> 
> 
> ----- 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.

Ah right, I've moved it to the right place.

> 
> > +    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?

I've made vm-guid as CONSTRUCT-ONLY, and I've made setting the vm-guid property
unset priv->vm

> > 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...)

Yes, thanks, I actually remembered that the 'foreign menu from .vv file' codepaths were untested, which explain this kind of bugs...  I will send a v2 with this code actually tested.
> 
> > +        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?
> 

Yup, added this break.

> > +        }
> > +    }
> > +    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?

Added too.


> > @@ -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?

Yup, thanks for catching that!

Christophe




More information about the virt-tools-list mailing list