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

Michal Privoznik mprivozn at redhat.com
Thu Sep 6 16:47:11 UTC 2012


as in nearly all cases users will install the guest
on current libvirt we've just obtained capabilities from.
---
 examples/virtxml.c |  119 ++++++++++++++++++++++++++++++++++++++-------------
 1 files changed, 88 insertions(+), 31 deletions(-)

diff --git a/examples/virtxml.c b/examples/virtxml.c
index 131c462..3e00e09 100644
--- a/examples/virtxml.c
+++ b/examples/virtxml.c
@@ -37,6 +37,9 @@
 #define print_error(...) \
     print_error_impl(__FUNCTION__, __LINE__, __VA_ARGS__)
 
+OsinfoLoader *loader = NULL;
+OsinfoDb *db = NULL;
+
 static void
 print_error_impl(const char *funcname,
                  size_t linenr,
@@ -74,12 +77,11 @@ print_usage(const char *progname)
            progname);
 }
 
-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);
@@ -88,8 +90,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);
@@ -99,11 +102,10 @@ cleanup:
 static int
 print_oses(void)
 {
-    OsinfoDb *db = get_default_osinfo_db();
     OsinfoOsList *list;
     int i;
 
-    if (!db)
+    if (!db && !load_osinfo())
         return EXIT_FAILURE;
 
     list = osinfo_db_get_os_list(db);
@@ -121,19 +123,16 @@ print_oses(void)
     }
 
     g_object_unref(list);
-    g_object_unref(db);
-
     return EXIT_SUCCESS;
 }
 
 static int
 print_platforms(void)
 {
-    OsinfoDb *db = get_default_osinfo_db();
     OsinfoPlatformList *list;
     int i;
 
-    if (!db)
+    if (!db && !load_osinfo())
         return EXIT_FAILURE;
 
     list = osinfo_db_get_platform_list(db);
@@ -152,8 +151,6 @@ print_platforms(void)
     }
 
     g_object_unref(list);
-    g_object_unref(db);
-
     return EXIT_SUCCESS;
 }
 
@@ -258,17 +255,10 @@ guess_os_from_disk(GList *disk_str_list)
 {
     OsinfoOs *ret = NULL;
     GList *tmp = g_list_first(disk_str_list);
-    OsinfoLoader *loader = osinfo_loader_new();
     GError *error = NULL;
-    OsinfoDb *db;
 
-    osinfo_loader_process_default_path(loader, &error);
-    if (error) {
-        print_error("Error loading libosinfo data: %s", error->message);
-        goto cleanup;
-    }
-
-    db = osinfo_loader_get_db(loader);
+    if (!db && !load_osinfo())
+        exit(EXIT_FAILURE);
 
     while (tmp) {
         char *path = (char *) tmp->data;
@@ -304,14 +294,75 @@ guess_os_from_disk(GList *disk_str_list)
     }
 
 cleanup:
-    g_clear_object(&loader);
+    return ret;
+}
+
+static OsinfoPlatform *
+find_platform_by_short_id(const char *short_id)
+{
+    OsinfoPlatform *ret = NULL;
+    OsinfoPlatformList *list = NULL;
+    int i;
+
+    if (!db && !load_osinfo())
+        return NULL;
+
+    list = osinfo_db_get_platform_list(db);
+
+    for (i = 0; i < osinfo_list_get_length(OSINFO_LIST(list)); i++) {
+        OsinfoPlatform *ent = OSINFO_PLATFORM(osinfo_list_get_nth(OSINFO_LIST(list), i));
+        const char *id = osinfo_entity_get_param_value(OSINFO_ENTITY(ent),
+                                                       OSINFO_PRODUCT_PROP_SHORT_ID);
+
+        if (id &&
+            !strcmp(id, short_id)) {
+            ret = ent;
+            g_object_ref(ret);
+            break;
+        }
+    }
+
+    g_object_unref(list);
     return ret;
 }
 
 static OsinfoPlatform *
 guess_platform_from_connect(virConnectPtr conn)
 {
-    return NULL;
+    OsinfoPlatform *ret = NULL;
+    const char *hv_type = virConnectGetType(conn);
+    unsigned long ver, major, minor, release;
+    int tmp;
+    char *short_id = NULL, *type = NULL;
+
+    tmp = virConnectGetVersion(conn, &ver);
+    if (!hv_type || tmp < 0) {
+        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 (!strcmp(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(type);
+    return ret;
 }
 
 #define CHECK_ERROR \
@@ -432,11 +483,6 @@ main(int argc, char *argv[])
         }
     }
 
-    if (!platform_str) {
-        print_error("Platform was not specified");
-        exit(EXIT_FAILURE);
-    }
-
     conn = virConnectOpenAuth(connect_uri, virConnectAuthPtrDefault, VIR_CONNECT_RO);
     if (!conn) {
         print_error("Unable to connect to libvirt");
@@ -448,7 +494,6 @@ main(int argc, char *argv[])
         goto cleanup;
     }
 
-    platform = osinfo_platform_new(platform_str);
     caps = gvir_config_capabilities_new_from_xml(caps_str, NULL);
 
     if (os_str) {
@@ -461,6 +506,18 @@ main(int argc, char *argv[])
         }
     }
 
+    if (platform_str) {
+        platform = osinfo_platform_new(platform_str);
+    } else {
+        platform = guess_platform_from_connect(conn);
+
+        if (!platform) {
+            print_error("Platform was not specified and could not be guessed");
+            exit(EXIT_FAILURE);
+        }
+    }
+
+
     domain = gvir_designer_domain_new(os, platform, caps);
 
     gvir_designer_domain_setup_machine(domain, &error);
-- 
1.7.8.6




More information about the libvir-list mailing list