[libvirt] [libvirt-designer][PATCH v2 3/4] virtxml: Detect platform from libvirt connection URI

Christophe Fergeau cfergeau at redhat.com
Fri Sep 14 16:17:14 UTC 2012


Looks good, ACK (would have been easier to review with the load_osinfo
changes in a separate patch, this would have halved the size of the patch
doing real code changes I think).

Christophe

On Thu, Sep 13, 2012 at 04:04:30PM +0200, Michal Privoznik wrote:
> as in nearly all cases users will install the guest
> on current libvirt we've just obtained capabilities from.
> ---
>  configure.ac       |    2 +-
>  examples/virtxml.c |  180 ++++++++++++++++++++++++++++++++++++++++------------
>  2 files changed, 139 insertions(+), 43 deletions(-)
> 
> diff --git a/configure.ac b/configure.ac
> index c214809..eb9c681 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -12,7 +12,7 @@ AM_SILENT_RULES([yes])
>  
>  LIBOSINFO_REQUIRED=0.0.5
>  LIBVIRT_GCONFIG_REQUIRED=0.0.9
> -LIBVIRT_GOBJECT_REQUIRED=0.0.8
> +LIBVIRT_GOBJECT_REQUIRED=0.1.3
>  GOBJECT_INTROSPECTION_REQUIRED=0.10.8
>  
>  LIBVIRT_DESIGNER_MAJOR_VERSION=`echo $VERSION | awk -F. '{print $1}'`
> diff --git a/examples/virtxml.c b/examples/virtxml.c
> index 4ec9cd8..cfe25ff 100644
> --- a/examples/virtxml.c
> +++ b/examples/virtxml.c
> @@ -35,6 +35,8 @@
>  
>  GList *disk_str_list = NULL;
>  GList *iface_str_list = NULL;
> +OsinfoLoader *loader = NULL;
> +OsinfoDb *db = NULL;
>  
>  #define print_error(...) \
>      print_error_impl(__FUNCTION__, __LINE__, __VA_ARGS__)
> @@ -58,12 +60,11 @@ print_error_impl(const char *funcname,
>      fprintf(stderr,"\n");
>  }
>  
> -static OsinfoDb *
> -get_default_osinfo_db(void)
> +static gboolean
> +load_osinfo(void)
>  {
>      GError *err = NULL;
> -    OsinfoLoader *loader = NULL;
> -    OsinfoDb *ret = NULL;
> +    gboolean ret = FALSE;
>  
>      loader = osinfo_loader_new();
>      osinfo_loader_process_default_path(loader, &err);
> @@ -72,8 +73,9 @@ get_default_osinfo_db(void)
>          goto cleanup;
>      }
>  
> -    ret = osinfo_loader_get_db(loader);
> -    g_object_ref(ret);
> +    db = osinfo_loader_get_db(loader);
> +    g_object_ref(db);
> +    ret = TRUE;
>  
>  cleanup:
>      g_object_unref(loader);
> @@ -96,13 +98,12 @@ print_oses(const gchar *option_name,
>             gpointer data,
>             GError **error)
>  {
> -    OsinfoDb *db = get_default_osinfo_db();
>      OsinfoOsList *list = NULL;
>      GList *oses = NULL;
>      GList *os_iter;
>      int ret = EXIT_FAILURE;
>  
> -    if (!db)
> +    if (!db && !load_osinfo())
>          goto cleanup;
>  
>      printf("  Operating System ID\n"
> @@ -126,8 +127,6 @@ print_oses(const gchar *option_name,
>  cleanup:
>      if (list)
>          g_object_unref(list);
> -    if (db)
> -        g_object_unref(db);
>  
>      exit(ret);
>      return TRUE;
> @@ -139,13 +138,12 @@ print_platforms(const gchar *option_name,
>                  gpointer data,
>                  GError **error)
>  {
> -    OsinfoDb *db = get_default_osinfo_db();
>      OsinfoPlatformList *list = NULL;
>      GList *platforms = NULL;
>      GList *platform_iter;
>      int ret = EXIT_FAILURE;
>  
> -    if (!db)
> +    if (!db && !load_osinfo())
>          goto cleanup;
>  
>      printf("  Platform ID\n"
> @@ -169,8 +167,6 @@ print_platforms(const gchar *option_name,
>  cleanup:
>      if (list)
>          g_object_unref(list);
> -    if (db)
> -        g_object_unref(db);
>  
>      exit(ret);
>      return TRUE;
> @@ -293,13 +289,34 @@ add_iface_str(const gchar *option_name,
>      return TRUE;
>  }
>  
> +static OsinfoEntity *
> +find_entity_by_short_id(OsinfoList *ent_list,
> +                        const char *short_id)
> +{
> +    OsinfoEntity *ret = NULL;
> +    GList *list, *list_iterator;
> +
> +    list = osinfo_list_get_elements(ent_list);
> +    for (list_iterator = list; list_iterator; list_iterator = list_iterator->next) {
> +        const char *id = osinfo_entity_get_param_value(list_iterator->data,
> +                                                       OSINFO_PRODUCT_PROP_SHORT_ID);
> +
> +        if (id && g_str_equal(id, short_id)) {
> +            ret = list_iterator->data;
> +            g_object_ref(ret);
> +            break;
> +        }
> +    }
> +
> +    return ret;
> +}
> +
>  static OsinfoOs *
>  find_os(const gchar *os_str)
>  {
> -    OsinfoDb *db = get_default_osinfo_db();
>      OsinfoOs *ret = NULL;
>  
> -    if (!db)
> +    if (!db && !load_osinfo())
>          return NULL;
>  
>      ret = osinfo_db_get_os(db, os_str);
> @@ -310,12 +327,11 @@ find_os(const gchar *os_str)
>  static OsinfoOs *
>  find_os_by_short_id(const char *short_id)
>  {
> -    OsinfoDb *db = get_default_osinfo_db();
>      OsinfoOs *ret = NULL;
>      OsinfoOsList *oses = NULL;
> -    GList *list, *list_iterator;
> +    OsinfoEntity *found = NULL;
>  
> -    if (!db)
> +    if (!db && !load_osinfo())
>          return NULL;
>  
>      oses = osinfo_db_get_os_list(db);
> @@ -323,21 +339,15 @@ find_os_by_short_id(const char *short_id)
>      if (!oses)
>          goto cleanup;
>  
> -    list = osinfo_list_get_elements(OSINFO_LIST(oses));
> -    for (list_iterator = list; list_iterator; list_iterator = list_iterator->next) {
> -        const char *id = osinfo_entity_get_param_value(list_iterator->data,
> -                                                       OSINFO_PRODUCT_PROP_SHORT_ID);
> -
> -        if (id && g_str_equal(id, short_id)) {
> -            ret = OSINFO_OS(list_iterator->data);
> -            g_object_ref(ret);
> -            break;
> -        }
> -    }
> +    found = find_entity_by_short_id(OSINFO_LIST(oses), short_id);
>  
> -    g_object_unref(oses);
> +    if (!found)
> +        goto cleanup;
> +    ret = OSINFO_OS(found);
>  
>  cleanup:
> +    if (oses)
> +        g_object_unref(oses);
>      return ret;
>  }
>  
> @@ -346,11 +356,9 @@ guess_os_from_disk(GList *disk_list)
>  {
>      OsinfoOs *ret = NULL;
>      GList *tmp = g_list_first(disk_list);
> -    OsinfoLoader *loader = osinfo_loader_new();
> -    OsinfoDb *db;
>  
> -    osinfo_loader_process_default_path(loader, NULL);
> -    db = osinfo_loader_get_db(loader);
> +    if (!db && !load_osinfo())
> +        return NULL;
>  
>      while (tmp) {
>          char *path = (char *) tmp->data;
> @@ -381,7 +389,88 @@ guess_os_from_disk(GList *disk_list)
>          tmp = g_list_next(tmp);
>      }
>  
> -    g_clear_object(&loader);
> +    return ret;
> +}
> +
> +static OsinfoPlatform *
> +find_platform(const char *platform_str)
> +{
> +    OsinfoPlatform *ret = NULL;
> +
> +    if (!db && !load_osinfo())
> +        return NULL;
> +
> +    ret = osinfo_db_get_platform(db, platform_str);
> +
> +    return ret;
> +}
> +
> +static OsinfoPlatform *
> +find_platform_by_short_id(const char *short_id)
> +{
> +    OsinfoPlatform *ret = NULL;
> +    OsinfoPlatformList *platforms = NULL;
> +    OsinfoEntity *found = NULL;
> +
> +    if (!db && !load_osinfo())
> +        goto cleanup;
> +
> +    platforms = osinfo_db_get_platform_list(db);
> +
> +    if (!platforms)
> +        goto cleanup;
> +
> +    found = find_entity_by_short_id(OSINFO_LIST(platforms), short_id);
> +
> +    if (!found)
> +        goto cleanup;
> +
> +    ret = OSINFO_PLATFORM(found);
> +
> +cleanup:
> +    if (platforms)
> +        g_object_unref(platforms);
> +    return ret;
> +}
> +
> +static OsinfoPlatform *
> +guess_platform_from_connect(GVirConnection *conn)
> +{
> +    OsinfoPlatform *ret = NULL;
> +    gchar *hv_type = NULL;
> +    gulong ver, major, minor, release;
> +    char *short_id = NULL, *type = NULL;
> +
> +    hv_type = gvir_connection_get_hypervisor_name(conn, NULL);
> +    ver = gvir_connection_get_version(conn, NULL);
> +
> +    if (!hv_type || !ver) {
> +        print_error("Unable to get hypervisor and its version");
> +        exit(EXIT_FAILURE);
> +    }
> +
> +    /* do some mappings:
> +     * QEMU -> kvm
> +     * Xen -> xen
> +     */
> +    type = g_ascii_strdown(hv_type, -1);
> +    if (g_str_equal(type, "qemu")) {
> +        g_free(type);
> +        type = g_strdup("kvm");
> +    }
> +
> +    major = ver / 1000000;
> +    ver %= 1000000;
> +    minor = ver / 1000;
> +    release = ver % 1000 ;
> +
> +    short_id = g_strdup_printf("%s-%lu.%lu.%lu", type, major, minor, release);
> +
> +    ret = find_platform_by_short_id(short_id);
> +
> +    g_free(short_id);
> +    g_free(hv_type);
> +    g_free(type);
>      return ret;
>  }
>  
> @@ -439,10 +528,6 @@ main(int argc, char *argv[])
>          g_print ("option parsing failed: %s\n", error->message);
>          return EXIT_FAILURE;
>      }
> -    if (!platform_str) {
> -        print_error("Platform was not specified");
> -        return EXIT_FAILURE;
> -    }
>  
>      conn = gvir_connection_new(connect_uri);
>      gvir_connection_open(conn, NULL, &error);
> @@ -451,8 +536,6 @@ main(int argc, char *argv[])
>      caps = gvir_connection_get_capabilities(conn, &error);
>      CHECK_ERROR;
>  
> -    platform = osinfo_platform_new(platform_str);
> -
>      if (os_str) {
>          os = find_os(os_str);
>          if (!os)
> @@ -466,6 +549,19 @@ main(int argc, char *argv[])
>          goto cleanup;
>      }
>  
> +    if (platform_str) {
> +        platform = find_platform(platform_str);
> +        if (!platform)
> +            platform = find_platform_by_short_id(platform_str);
> +    } else {
> +        platform = guess_platform_from_connect(conn);
> +    }
> +
> +    if (!platform) {
> +        print_error("Platform was not specified or could not be guessed");
> +        goto cleanup;
> +    }
> +
>      domain = gvir_designer_domain_new(os, platform, caps);
>  
>      gvir_designer_domain_setup_machine(domain, &error);
> -- 
> 1.7.8.6
> 
> --
> libvir-list mailing list
> libvir-list at redhat.com
> https://www.redhat.com/mailman/listinfo/libvir-list
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20120914/7617cc9e/attachment-0001.sig>


More information about the libvir-list mailing list