[virt-tools-list] [libosinfo PATCHv2 02/11] loader: Load datamaps

Christophe Fergeau cfergeau at redhat.com
Tue Dec 11 18:20:06 UTC 2012


Install scripts can add a 'datamap' attribute when they declare
their config parameters. The value of this attribute is the ID
of a datamap, which is an XML file containing key/value pairs:

<?xml version="1.0" encoding="UTF-8"?>
<libosinfo version="0.0.1">
  <datamap id="http://example.com/osinfo/test">
    <entry>
      <inval>generic-val1</inval>
      <outval>foo</outval>
    </entry>
    <entry>
      <inval>generic-val2</inval>
      <outval>bar</outval>
    </entry>
  </datamap>
</libosinfo>

This commit adds support for loading these datamaps. The next patches
will then make use of these datamaps when the libosinfo user set
a value for the corresponding config parameter.
---
 osinfo/libosinfo.syms  |  4 +++
 osinfo/osinfo_db.c     | 51 ++++++++++++++++++++++++++++
 osinfo/osinfo_db.h     |  3 ++
 osinfo/osinfo_loader.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++-
 4 files changed, 147 insertions(+), 1 deletion(-)

diff --git a/osinfo/libosinfo.syms b/osinfo/libosinfo.syms
index 35525a0..37736f1 100644
--- a/osinfo/libosinfo.syms
+++ b/osinfo/libosinfo.syms
@@ -382,6 +382,10 @@ LIBOSINFO_0.2.3 {
 
 	osinfo_datamaplist_get_type;
 	osinfo_datamaplist_new;
+
+	osinfo_db_add_datamap;
+	osinfo_db_get_datamap;
+	osinfo_db_get_datamap_list;
 } LIBOSINFO_0.2.2;
 
 /* Symbols in next release...
diff --git a/osinfo/osinfo_db.c b/osinfo/osinfo_db.c
index c17c512..dcda2fe 100644
--- a/osinfo/osinfo_db.c
+++ b/osinfo/osinfo_db.c
@@ -53,6 +53,7 @@ struct _OsinfoDbPrivate
     OsinfoPlatformList *platforms;
     OsinfoOsList *oses;
     OsinfoDeploymentList *deployments;
+    OsinfoDatamapList *datamaps;
     OsinfoInstallScriptList *scripts;
 };
 
@@ -67,6 +68,7 @@ osinfo_db_finalize (GObject *object)
     g_object_unref(db->priv->platforms);
     g_object_unref(db->priv->oses);
     g_object_unref(db->priv->deployments);
+    g_object_unref(db->priv->datamaps);
     g_object_unref(db->priv->scripts);
 
     /* Chain up to the parent class */
@@ -96,6 +98,7 @@ osinfo_db_init (OsinfoDb *db)
     db->priv->platforms = osinfo_platformlist_new();
     db->priv->oses = osinfo_oslist_new();
     db->priv->deployments = osinfo_deploymentlist_new();
+    db->priv->datamaps = osinfo_datamaplist_new();
     db->priv->scripts = osinfo_install_scriptlist_new();
 }
 
@@ -173,6 +176,22 @@ OsinfoDeployment *osinfo_db_get_deployment(OsinfoDb *db, const gchar *id)
 }
 
 /**
+ * osinfo_db_get_datamap:
+ * @db: the database
+ * @id: the unique operating system identifier
+ *
+ * Returns: (transfer none): the install datamap, or NULL if none is found
+ */
+OsinfoDatamap *osinfo_db_get_datamap(OsinfoDb *db, const gchar *id)
+{
+    g_return_val_if_fail(OSINFO_IS_DB(db), NULL);
+    g_return_val_if_fail(id != NULL, NULL);
+
+    return OSINFO_DATAMAP(osinfo_list_find_by_id(OSINFO_LIST(db->priv->datamaps), id));
+}
+
+
+/**
  * osinfo_db_get_install_script:
  * @db: the database
  * @id: the unique operating system identifier
@@ -297,6 +316,23 @@ OsinfoDeploymentList *osinfo_db_get_deployment_list(OsinfoDb *db)
 
 
 /**
+ * osinfo_db_get_install_datamap_list:
+ * @db: the database
+ *
+ * Returns: (transfer full): the list of install datamaps
+ */
+OsinfoDatamapList *osinfo_db_get_datamap_list(OsinfoDb *db)
+{
+    OsinfoList *new_list;
+
+    g_return_val_if_fail(OSINFO_IS_DB(db), NULL);
+    new_list = osinfo_list_new_copy(OSINFO_LIST(db->priv->datamaps));
+
+    return OSINFO_DATAMAPLIST(new_list);
+}
+
+
+/**
  * osinfo_db_get_install_script_list:
  * @db: the database
  *
@@ -374,6 +410,21 @@ void osinfo_db_add_deployment(OsinfoDb *db, OsinfoDeployment *deployment)
 
 
 /**
+ * osinfo_db_add_datamap:
+ * @db: the database
+ * @datamap: (transfer none): a install datamap
+ *
+ */
+void osinfo_db_add_datamap(OsinfoDb *db, OsinfoDatamap *datamap)
+{
+    g_return_if_fail(OSINFO_IS_DB(db));
+    g_return_if_fail(OSINFO_IS_DATAMAP(datamap));
+
+    osinfo_list_add(OSINFO_LIST(db->priv->datamaps), OSINFO_ENTITY(datamap));
+}
+
+
+/**
  * osinfo_db_add_install_script:
  * @db: the database
  * @script: (transfer none): a install script
diff --git a/osinfo/osinfo_db.h b/osinfo/osinfo_db.h
index 0effefd..824a224 100644
--- a/osinfo/osinfo_db.h
+++ b/osinfo/osinfo_db.h
@@ -79,6 +79,7 @@ OsinfoPlatform *osinfo_db_get_platform(OsinfoDb *db, const gchar *id);
 OsinfoDevice *osinfo_db_get_device(OsinfoDb *db, const gchar *id);
 OsinfoOs *osinfo_db_get_os(OsinfoDb *db, const gchar *id);
 OsinfoDeployment *osinfo_db_get_deployment(OsinfoDb *db, const gchar *id);
+OsinfoDatamap *osinfo_db_get_datamap(OsinfoDb *db, const gchar *id);
 OsinfoInstallScript *osinfo_db_get_install_script(OsinfoDb *db, const gchar *id);
 
 OsinfoDeployment *osinfo_db_find_deployment(OsinfoDb *db,
@@ -90,11 +91,13 @@ OsinfoPlatformList *osinfo_db_get_platform_list(OsinfoDb *db);
 OsinfoDeviceList *osinfo_db_get_device_list(OsinfoDb *db);
 OsinfoDeploymentList *osinfo_db_get_deployment_list(OsinfoDb *db);
 OsinfoInstallScriptList *osinfo_db_get_install_script_list(OsinfoDb *db);
+OsinfoDatamapList *osinfo_db_get_datamap_list(OsinfoDb *db);
 
 void osinfo_db_add_os(OsinfoDb *db, OsinfoOs *os);
 void osinfo_db_add_platform(OsinfoDb *db, OsinfoPlatform *platform);
 void osinfo_db_add_device(OsinfoDb *db, OsinfoDevice *device);
 void osinfo_db_add_deployment(OsinfoDb *db, OsinfoDeployment *deployment);
+void osinfo_db_add_datamap(OsinfoDb *db, OsinfoDatamap *datamap);
 void osinfo_db_add_install_script(OsinfoDb *db, OsinfoInstallScript *script);
 
 OsinfoOs *osinfo_db_guess_os_from_media(OsinfoDb *db,
diff --git a/osinfo/osinfo_loader.c b/osinfo/osinfo_loader.c
index 18325f6..f4918a8 100644
--- a/osinfo/osinfo_loader.c
+++ b/osinfo/osinfo_loader.c
@@ -287,6 +287,18 @@ static void osinfo_loader_entity(OsinfoLoader *loader,
     g_free(custom);
 }
 
+static OsinfoDatamap *osinfo_loader_get_datamap(OsinfoLoader *loader,
+                                                 const gchar *id)
+{
+    OsinfoDatamap *datamap = osinfo_db_get_datamap(loader->priv->db, id);
+    if (!datamap) {
+        datamap = osinfo_datamap_new(id);
+        osinfo_db_add_datamap(loader->priv->db, datamap);
+        g_object_unref(datamap);
+    }
+    return datamap;
+}
+
 static OsinfoDevice *osinfo_loader_get_device(OsinfoLoader *loader,
                                               const gchar *id)
 {
@@ -574,6 +586,67 @@ static void osinfo_loader_deployment(OsinfoLoader *loader,
     osinfo_db_add_deployment(loader->priv->db, deployment);
 }
 
+static void osinfo_loader_datamap_entry(OsinfoLoader *loader,
+                                        OsinfoDatamap *map,
+                                        xmlXPathContextPtr ctxt,
+                                        xmlNodePtr root,
+                                        GError **err)
+{
+    gchar *inval = NULL;
+    gchar *outval = NULL;
+
+    inval = osinfo_loader_string("string(./inval)", ctxt, err);
+    if (error_is_set(err) || (inval == NULL))
+        goto end;
+
+    outval = osinfo_loader_string("string(./outval)", ctxt, err);
+    if (error_is_set(err))
+        goto end;
+
+    osinfo_datamap_insert(map, inval, outval);
+
+end:
+    g_free(inval);
+    g_free(outval);
+}
+
+static void osinfo_loader_datamap(OsinfoLoader *loader,
+                                  xmlXPathContextPtr ctxt,
+                                  xmlNodePtr root,
+                                  GError **err)
+{
+    xmlNodePtr *nodes = NULL;
+    guint i;
+    int nnodes;
+
+    gchar *id = (gchar *)xmlGetProp(root, BAD_CAST "id");
+
+    if (!id) {
+        OSINFO_ERROR(err, _("Missing os id property"));
+        return;
+    }
+
+    OsinfoDatamap *map = osinfo_loader_get_datamap(loader, id);
+
+    nnodes = osinfo_loader_nodeset("./entry", ctxt, &nodes, err);
+    if (error_is_set(err))
+        goto cleanup;
+
+    for (i = 0 ; i < nnodes ; i++) {
+        xmlNodePtr saved = ctxt->node;
+
+        ctxt->node = nodes[i];
+        osinfo_loader_datamap_entry(loader, map, ctxt, root, err);
+        if (error_is_set(err))
+            goto cleanup;
+        ctxt->node = saved;
+    }
+
+cleanup:
+    g_free(nodes);
+    xmlFree(id);
+}
+
 static void osinfo_loader_install_config_params(OsinfoLoader *loader,
                                                 OsinfoEntity *entity,
                                                 const gchar *xpath,
@@ -1150,7 +1223,7 @@ static void osinfo_loader_root(OsinfoLoader *loader,
      *   If closing libosinfo tag, break
      *   If non element tag, continue
      *   If element tag, and element is not os, platform, device,
-     *   deployment or install-script, error
+     *   datamap, deployment or install-script, error
      *   Else, switch on tag type and handle reading in data
      * After loop, return success if no error
      * If there was an error, clean up lib data acquired so far
@@ -1160,12 +1233,14 @@ static void osinfo_loader_root(OsinfoLoader *loader,
     xmlNodePtr *platforms = NULL;
     xmlNodePtr *deployments = NULL;
     xmlNodePtr *installScripts = NULL;
+    xmlNodePtr *dataMaps = NULL;
     int i;
     int ndeployment;
     int nos;
     int ndevice;
     int nplatform;
     int ninstallScript;
+    int ndataMaps;
 
     if (!xmlStrEqual(root->name, BAD_CAST "libosinfo")) {
         OSINFO_ERROR(err, _("Incorrect root element"));
@@ -1237,8 +1312,21 @@ static void osinfo_loader_root(OsinfoLoader *loader,
             goto cleanup;
     }
 
+    ndataMaps = osinfo_loader_nodeset("./datamap", ctxt, &dataMaps, err);
+    if (error_is_set(err))
+        goto cleanup;
+
+    for (i = 0 ; i < ndataMaps ; i++) {
+        xmlNodePtr saved = ctxt->node;
+        ctxt->node = dataMaps[i];
+        osinfo_loader_datamap(loader, ctxt, dataMaps[i], err);
+        ctxt->node = saved;
+        if (error_is_set(err))
+            goto cleanup;
+    }
 
  cleanup:
+    g_free(dataMaps);
     g_free(installScripts);
     g_free(deployments);
     g_free(platforms);
-- 
1.8.0.1




More information about the virt-tools-list mailing list