[virt-tools-list] [PATCH libosinfo 3/7] Associate install scripts with operating systems

Daniel P. Berrange berrange at redhat.com
Tue Feb 28 15:26:19 UTC 2012


From: "Daniel P. Berrange" <berrange at redhat.com>

Operating systems now get a new element

    <installer>
      <script id='http://fedoraproject.org/scripts/fedora/jeos'/>
    </installer>

And there is a new top level element to go along with
this:

  <install-script id='http://fedoraproject.org/scripts/fedora/jeos'>
    <profile>jeos</profile>
    <template>
      <xsl:stylesheet
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        version="1.0">
       ....template for install script...
	</xsl:template>
      </xsl:stylesheet>
    </template>
  </install-script>
---
 data/schemas/libosinfo.rng |   62 +++++++++++++++++++
 osinfo/libosinfo.syms      |    6 ++
 osinfo/osinfo_db.c         |   48 +++++++++++++++
 osinfo/osinfo_db.h         |    3 +
 osinfo/osinfo_loader.c     |  142 ++++++++++++++++++++++++++++++++++++++++++++
 osinfo/osinfo_os.c         |   39 ++++++++++++
 osinfo/osinfo_os.h         |   12 +++-
 7 files changed, 310 insertions(+), 2 deletions(-)

diff --git a/data/schemas/libosinfo.rng b/data/schemas/libosinfo.rng
index 594da7b..92499f9 100644
--- a/data/schemas/libosinfo.rng
+++ b/data/schemas/libosinfo.rng
@@ -337,6 +337,18 @@
     </element>
   </define>
 
+  <define name='installer'>
+    <element name='installer'>
+      <zeroOrMore>
+	<element name="script">
+	  <attribute name='id'>
+	    <ref name='url'/>
+	  </attribute>
+	</element>
+      </zeroOrMore>
+    </element>
+  </define>
+
   <define name='os'>
     <element name='os'>
       <ref name='product-attr'/>
@@ -361,6 +373,9 @@
         <zeroOrMore>
           <ref name='tree'/>
         </zeroOrMore>
+	<zeroOrMore>
+          <ref name='installer'/>
+        </zeroOrMore>
       </interleave>
     </element>
   </define>
@@ -385,6 +400,53 @@
     </element>
   </define>
 
+  <define name='install-script'>
+    <element name='install-script'>
+      <attribute name='id'>
+        <ref name='url'/>
+      </attribute>
+      <element name='profile'>
+	<text/>
+      </element>
+      <element name='product-key-format'>
+	<text/>
+      </element>
+      <element name='template'>
+	<choice>
+	  <group>
+	    <attribute name="uri"/>
+	    <empty/>
+	  </group>
+	  <ref name="customElement"/>
+	</choice>
+      </element>
+      <ref name='product-attr'/>
+      <ref name='product-content'/>
+      <interleave>
+        <ref name='product-dates'/>
+        <ref name='product-rel'/>
+        <optional>
+          <ref name='devices-rel'/>
+        </optional>
+      </interleave>
+    </element>
+  </define>
+
+  <define name="customElement">
+    <element>
+      <anyName/>
+      <zeroOrMore>
+        <choice>
+          <attribute>
+            <anyName/>
+          </attribute>
+          <text/>
+          <ref name="customElement"/>
+        </choice>
+      </zeroOrMore>
+    </element>
+  </define>
+
   <define name='date'>
     <data type="string">
       <param name="pattern">[0-9]{4}-[0-9]{2}-[0-9]{2}</param>
diff --git a/osinfo/libosinfo.syms b/osinfo/libosinfo.syms
index a9bb5c2..6af23cd 100644
--- a/osinfo/libosinfo.syms
+++ b/osinfo/libosinfo.syms
@@ -267,6 +267,12 @@ LIBOSINFO_0.1.0 {
 	osinfo_treelist_new_filtered;
 	osinfo_treelist_new_intersection;
 	osinfo_treelist_new_union;
+	osinfo_db_get_install_script;
+	osinfo_db_add_install_script;
+	osinfo_db_get_install_scripts;
+	osinfo_os_get_install_script;
+	osinfo_os_get_install_scripts;
+	osinfo_os_add_install_script;
 } LIBOSINFO_0.0.6;
 
 /* Symbols in next release...
diff --git a/osinfo/osinfo_db.c b/osinfo/osinfo_db.c
index 6a8f4d1..6ae8a82 100644
--- a/osinfo/osinfo_db.c
+++ b/osinfo/osinfo_db.c
@@ -52,6 +52,7 @@ struct _OsinfoDbPrivate
     OsinfoPlatformList *platforms;
     OsinfoOsList *oses;
     OsinfoDeploymentList *deployments;
+    OsinfoInstallScriptList *scripts;
 };
 
 static void osinfo_db_finalize (GObject *object);
@@ -65,6 +66,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->scripts);
 
     /* Chain up to the parent class */
     G_OBJECT_CLASS (osinfo_db_parent_class)->finalize (object);
@@ -93,6 +95,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->scripts = osinfo_install_scriptlist_new();
 }
 
 /** PUBLIC METHODS */
@@ -168,6 +171,21 @@ OsinfoDeployment *osinfo_db_get_deployment(OsinfoDb *db, const gchar *id)
     return OSINFO_DEPLOYMENT(osinfo_list_find_by_id(OSINFO_LIST(db->priv->deployments), id));
 }
 
+/**
+ * osinfo_db_get_install_script:
+ * @db: the database
+ * @id: the unique operating system identifier
+ *
+ * Returns: (transfer none): the install script, or NULL if none is found
+ */
+OsinfoInstallScript *osinfo_db_get_install_script(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_INSTALL_SCRIPT(osinfo_list_find_by_id(OSINFO_LIST(db->priv->scripts), id));
+}
+
 
 /**
  * osinfo_db_find_deployment:
@@ -266,6 +284,20 @@ OsinfoDeploymentList *osinfo_db_get_deployment_list(OsinfoDb *db)
 
 
 /**
+ * osinfo_db_get_install_script_list:
+ * @db: the database
+ *
+ * Returns: (transfer full): the list of install scripts
+ */
+OsinfoInstallScriptList *osinfo_db_get_install_script_list(OsinfoDb *db)
+{
+    g_return_val_if_fail(OSINFO_IS_DB(db), NULL);
+
+    return osinfo_install_scriptlist_new_copy(db->priv->scripts);
+}
+
+
+/**
  * osinfo_db_add_os:
  * @db: the database
  * @os: (transfer none): an operating system
@@ -324,6 +356,22 @@ void osinfo_db_add_deployment(OsinfoDb *db, OsinfoDeployment *deployment)
     osinfo_list_add(OSINFO_LIST(db->priv->deployments), OSINFO_ENTITY(deployment));
 }
 
+
+/**
+ * osinfo_db_add_install_script:
+ * @db: the database
+ * @script: (transfer none): a install script
+ *
+ */
+void osinfo_db_add_install_script(OsinfoDb *db, OsinfoInstallScript *script)
+{
+    g_return_if_fail(OSINFO_IS_DB(db));
+    g_return_if_fail(OSINFO_IS_INSTALL_SCRIPT(script));
+
+    osinfo_list_add(OSINFO_LIST(db->priv->scripts), OSINFO_ENTITY(script));
+}
+
+
 static gint media_volume_compare (gconstpointer a, gconstpointer b)
 {
     OsinfoMedia *media_a = OSINFO_MEDIA(a);
diff --git a/osinfo/osinfo_db.h b/osinfo/osinfo_db.h
index d549bf9..d789802 100644
--- a/osinfo/osinfo_db.h
+++ b/osinfo/osinfo_db.h
@@ -78,6 +78,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);
+OsinfoInstallScript *osinfo_db_get_install_script(OsinfoDb *db, const gchar *id);
 
 OsinfoDeployment *osinfo_db_find_deployment(OsinfoDb *db,
                                             OsinfoOs *os,
@@ -87,11 +88,13 @@ OsinfoOsList *osinfo_db_get_os_list(OsinfoDb *db);
 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);
 
 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_install_script(OsinfoDb *db, OsinfoInstallScript *script);
 
 OsinfoOs *osinfo_db_guess_os_from_media(OsinfoDb *db,
                                         OsinfoMedia *media,
diff --git a/osinfo/osinfo_loader.c b/osinfo/osinfo_loader.c
index 6d57e6e..1f3d384 100644
--- a/osinfo/osinfo_loader.c
+++ b/osinfo/osinfo_loader.c
@@ -172,6 +172,45 @@ osinfo_loader_string(const char *xpath,
     return ret;
 }
 
+static gchar *
+osinfo_loader_doc(const char *xpath,
+                  xmlXPathContextPtr ctxt,
+                  GError **err)
+{
+    xmlXPathObjectPtr obj;
+    xmlNodePtr relnode;
+    gchar *ret;
+    xmlBufferPtr buf;
+
+    g_return_val_if_fail(ctxt != NULL, NULL);
+    g_return_val_if_fail(xpath != NULL, NULL);
+
+    relnode = ctxt->node;
+    obj = xmlXPathEval(BAD_CAST xpath, ctxt);
+    ctxt->node = relnode;
+    if ((obj == NULL) || (obj->type != XPATH_NODESET)) {
+        xmlXPathFreeObject(obj);
+        return NULL;
+    }
+
+    if (!(buf = xmlBufferCreate())) {
+        xmlXPathFreeObject(obj);
+        g_set_error(err, 0, 0, "%s",
+                    "Cannot allocate buffer");
+        return NULL;
+    }
+    if (xmlNodeDump(buf, NULL, obj->nodesetval->nodeTab[0], 0, 1) < 0) {
+        xmlXPathFreeObject(obj);
+        g_set_error(err, 0, 0, "%s",
+                    "Cannot format stylesheet");
+    }
+    ret = g_strdup((char *)buf->content);
+
+    xmlBufferFree(buf);
+    xmlXPathFreeObject(obj);
+    return ret;
+}
+
 static void osinfo_loader_entity(OsinfoLoader *loader,
                                  OsinfoEntity *entity,
                                  const gchar *const *keys,
@@ -255,6 +294,18 @@ static OsinfoPlatform *osinfo_loader_get_platform(OsinfoLoader *loader,
     return platform;
 }
 
+static OsinfoInstallScript *osinfo_loader_get_install_script(OsinfoLoader *loader,
+                                                             const gchar *id)
+{
+    OsinfoInstallScript *script = osinfo_db_get_install_script(loader->priv->db, id);
+    if (!script) {
+        script = osinfo_install_script_new(id);
+        osinfo_db_add_install_script(loader->priv->db, script);
+        g_object_unref(script);
+    }
+    return script;
+}
+
 static void osinfo_loader_device(OsinfoLoader *loader,
                                  xmlXPathContextPtr ctxt,
                                  xmlNodePtr root,
@@ -487,6 +538,60 @@ static void osinfo_loader_deployment(OsinfoLoader *loader,
     osinfo_db_add_deployment(loader->priv->db, deployment);
 }
 
+
+static void osinfo_loader_install_script(OsinfoLoader *loader,
+                                         xmlXPathContextPtr ctxt,
+                                         xmlNodePtr root,
+                                         GError **err)
+{
+    gchar *id = (gchar *)xmlGetProp(root, BAD_CAST "id");
+    const gchar *const keys[] = {
+        OSINFO_INSTALL_SCRIPT_PROP_PROFILE,
+        OSINFO_INSTALL_SCRIPT_PROP_PRODUCT_KEY_FORMAT,
+        NULL
+    };
+    gchar *value = NULL;
+
+    if (!id) {
+        OSINFO_ERROR(err, "Missing install script id property");
+        return;
+    }
+
+    OsinfoInstallScript *installScript = osinfo_loader_get_install_script(loader,
+                                                                          id);
+    g_free(id);
+
+    osinfo_loader_entity(loader, OSINFO_ENTITY(installScript), keys, ctxt, root, err);
+    if (error_is_set(err))
+        goto error;
+
+    value = osinfo_loader_doc("./template/*[1]", ctxt, err);
+    if (error_is_set(err))
+        goto error;
+    if (value)
+        osinfo_entity_set_param(OSINFO_ENTITY(installScript),
+                                OSINFO_INSTALL_SCRIPT_PROP_TEMPLATE_DATA,
+                                value);
+    g_free(value);
+
+    value = osinfo_loader_string("./template/@uri", ctxt, err);
+    if (error_is_set(err))
+        goto error;
+    if (value)
+        osinfo_entity_set_param(OSINFO_ENTITY(installScript),
+                                OSINFO_INSTALL_SCRIPT_PROP_TEMPLATE_URI,
+                                value);
+    g_free(value);
+
+    osinfo_db_add_install_script(loader->priv->db, installScript);
+
+    return;
+
+ error:
+    g_free(value);
+    g_object_unref(installScript);
+}
+
 static OsinfoMedia *osinfo_loader_media (OsinfoLoader *loader,
                                          xmlXPathContextPtr ctxt,
                                          xmlNodePtr root,
@@ -773,6 +878,27 @@ static void osinfo_loader_os(OsinfoLoader *loader,
 
     g_free(nodes);
 
+
+    nnodes = osinfo_loader_nodeset("./installer/script", ctxt, &nodes, err);
+    if (error_is_set(err))
+        return;
+
+    for (i = 0 ; i < nnodes ; i++) {
+        gchar *scriptid = (gchar *)xmlGetProp(nodes[i], BAD_CAST "id");
+        if (!scriptid) {
+            OSINFO_ERROR(err, "Missing OS install script property");
+            g_free(nodes);
+            goto cleanup;
+        }
+        OsinfoInstallScript *script;
+        script = osinfo_loader_get_install_script(loader, scriptid);
+        g_free(scriptid);
+
+        osinfo_os_add_install_script(os, script);
+    }
+
+    g_free(nodes);
+
 cleanup:
     g_free(id);
 }
@@ -801,11 +927,13 @@ static void osinfo_loader_root(OsinfoLoader *loader,
     xmlNodePtr *devices = NULL;
     xmlNodePtr *platforms = NULL;
     xmlNodePtr *deployments = NULL;
+    xmlNodePtr *installScripts = NULL;
     int i;
     int ndeployment;
     int nos;
     int ndevice;
     int nplatform;
+    int ninstallScript;
 
     if (!xmlStrEqual(root->name, BAD_CAST "libosinfo")) {
         OSINFO_ERROR(err, "Incorrect root element");
@@ -864,8 +992,22 @@ static void osinfo_loader_root(OsinfoLoader *loader,
             goto cleanup;
     }
 
+    ninstallScript = osinfo_loader_nodeset("./install-script", ctxt, &installScripts, err);
+    if (error_is_set(err))
+        goto cleanup;
+
+    for (i = 0 ; i < ninstallScript ; i++) {
+        xmlNodePtr saved = ctxt->node;
+        ctxt->node = installScripts[i];
+        osinfo_loader_install_script(loader, ctxt, installScripts[i], err);
+        ctxt->node = saved;
+        if (error_is_set(err))
+            goto cleanup;
+    }
+
 
  cleanup:
+    g_free(installScripts);
     g_free(deployments);
     g_free(platforms);
     g_free(oss);
diff --git a/osinfo/osinfo_os.c b/osinfo/osinfo_os.c
index 4b91142..d1d5d22 100644
--- a/osinfo/osinfo_os.c
+++ b/osinfo/osinfo_os.c
@@ -51,6 +51,8 @@ struct _OsinfoOsPrivate
     OsinfoTreeList *trees;
     OsinfoResourcesList *minimum;
     OsinfoResourcesList *recommended;
+
+    OsinfoInstallScriptList *scripts;
 };
 
 struct _OsinfoOsDeviceLink {
@@ -103,6 +105,8 @@ osinfo_os_finalize (GObject *object)
     g_object_unref(os->priv->medias);
     g_object_unref(os->priv->trees);
 
+    g_object_unref(os->priv->scripts);
+
     /* Chain up to the parent class */
     G_OBJECT_CLASS (osinfo_os_parent_class)->finalize (object);
 }
@@ -149,6 +153,7 @@ osinfo_os_init (OsinfoOs *os)
     os->priv->trees = osinfo_treelist_new ();
     os->priv->minimum = osinfo_resourceslist_new ();
     os->priv->recommended = osinfo_resourceslist_new ();
+    os->priv->scripts = osinfo_install_scriptlist_new ();
 }
 
 /**
@@ -487,6 +492,40 @@ void osinfo_os_add_recommended_resources(OsinfoOs *os,
                     OSINFO_ENTITY(resources));
 }
 
+
+OsinfoInstallScript *osinfo_os_find_install_script(OsinfoOs *os, const gchar *profile)
+{
+    g_return_val_if_fail(OSINFO_IS_OS(os), NULL);
+    GList *scripts = osinfo_list_get_elements(OSINFO_LIST(os));
+    GList *tmp = scripts;
+
+    while (tmp) {
+        OsinfoInstallScript *script = tmp->data;
+        if (g_str_equal(profile, osinfo_install_script_get_profile(script)))
+            return script;
+
+        tmp = tmp->next;
+    }
+
+    return NULL;
+}
+
+
+OsinfoInstallScriptList *osinfo_os_get_install_scripts(OsinfoOs *os)
+{
+    g_return_val_if_fail(OSINFO_IS_OS(os), NULL);
+
+    return osinfo_install_scriptlist_new_copy(os->priv->scripts);
+}
+
+
+void osinfo_os_add_install_script(OsinfoOs *os, OsinfoInstallScript *script)
+{
+    g_return_if_fail(OSINFO_IS_OS(os));
+
+    osinfo_list_add(OSINFO_LIST(os->priv->scripts), OSINFO_ENTITY(script));
+}
+
 /*
  * Local variables:
  *  indent-tabs-mode: nil
diff --git a/osinfo/osinfo_os.h b/osinfo/osinfo_os.h
index ca16dc3..fef0525 100644
--- a/osinfo/osinfo_os.h
+++ b/osinfo/osinfo_os.h
@@ -46,8 +46,11 @@
 #define OSINFO_IS_OS_CLASS(klass)       (G_TYPE_CHECK_CLASS_TYPE ((klass), OSINFO_TYPE_OS))
 #define OSINFO_OS_GET_CLASS(obj)        (G_TYPE_INSTANCE_GET_CLASS ((obj), OSINFO_TYPE_OS, OsinfoOsClass))
 
-typedef struct _OsinfoOs        OsinfoOs;
-
+/*
+ * Forward declared in osinfo_install_script.h
+ *
+ * typedef struct _OsinfoOs        OsinfoOs;
+ */
 typedef struct _OsinfoOsClass   OsinfoOsClass;
 
 typedef struct _OsinfoOsPrivate OsinfoOsPrivate;
@@ -96,6 +99,11 @@ OsinfoResourcesList *osinfo_os_get_recommended_resources(OsinfoOs *os);
 void osinfo_os_add_minimum_resources(OsinfoOs *os, OsinfoResources *resources);
 void osinfo_os_add_recommended_resources(OsinfoOs *os, OsinfoResources *resources);
 
+OsinfoInstallScript *osinfo_os_get_install_script(OsinfoOs *os, const gchar *id);
+OsinfoInstallScript *osinfo_os_find_install_script(OsinfoOs *os, const gchar *profile);
+OsinfoInstallScriptList *osinfo_os_get_install_scripts(OsinfoOs *os);
+void osinfo_os_add_install_script(OsinfoOs *os, OsinfoInstallScript *script);
+
 #endif /* __OSINFO_OS_H__ */
 /*
  * Local variables:
-- 
1.7.7.6




More information about the virt-tools-list mailing list