[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