[libvirt] [libvirt-glib] API to get/set custom metadata from/to domain config

Zeeshan Ali (Khattak) zeeshanak at gnome.org
Fri Jan 20 21:11:57 UTC 2012


From: "Zeeshan Ali (Khattak)" <zeeshanak at gnome.org>

---
 libvirt-gconfig/libvirt-gconfig-domain.c  |  115 +++++++++++++++++++++++++++++
 libvirt-gconfig/libvirt-gconfig-domain.h  |    8 ++
 libvirt-gconfig/libvirt-gconfig-helpers.c |    4 +-
 libvirt-gconfig/libvirt-gconfig.sym       |    2 +
 4 files changed, 128 insertions(+), 1 deletions(-)

diff --git a/libvirt-gconfig/libvirt-gconfig-domain.c b/libvirt-gconfig/libvirt-gconfig-domain.c
index 61af625..d1faabd 100644
--- a/libvirt-gconfig/libvirt-gconfig-domain.c
+++ b/libvirt-gconfig/libvirt-gconfig-domain.c
@@ -449,3 +449,118 @@ GList *gvir_config_domain_get_devices(GVirConfigDomain *domain)
 
     return data.devices;
 }
+
+static void set_namespace_on_tree(xmlNodePtr node, xmlNsPtr namespace)
+{
+    xmlNodePtr child;
+
+    xmlSetNs(node, namespace);
+
+    for (child = node->children; child != NULL; child = child->next)
+        set_namespace_on_tree(child, namespace);
+}
+
+static xmlNodePtr gvir_config_domain_get_metadata_node
+        (GVirConfigDomain *domain, gboolean create)
+{
+    xmlNodePtr domain_node, metadata_node;
+
+    domain_node = gvir_config_object_get_xml_node(GVIR_CONFIG_OBJECT(domain));
+    metadata_node = gvir_config_xml_get_element(domain_node, "metadata", NULL);
+    if (metadata_node == NULL && create)
+        metadata_node = xmlNewChild(domain_node, NULL, (xmlChar *)"metadata", NULL);
+
+    return metadata_node;
+}
+
+static xmlNodePtr gvir_config_domain_get_custom_xml_node
+        (GVirConfigDomain *domain, const gchar *ns_uri)
+{
+    xmlNodePtr metadata_node, node;
+
+    g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN(domain), NULL);
+
+    metadata_node = gvir_config_domain_get_metadata_node(domain, FALSE);
+    if (metadata_node == NULL)
+        return NULL;
+
+    for (node = metadata_node->children; node != NULL; node = node->next) {
+        if (node->ns != NULL &&
+            (g_strcmp0 ((gchar *)node->ns->href, ns_uri) == 0))
+            break;
+    }
+
+    return node;
+}
+
+gboolean gvir_config_domain_set_custom_xml(GVirConfigDomain *domain,
+                                           const gchar *xml,
+                                           const gchar *ns,
+                                           const gchar *ns_uri,
+                                           GError **error)
+{
+    xmlNodePtr metadata_node, node, old_node;
+    xmlDocPtr doc;
+    xmlNsPtr namespace;
+
+    g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN(domain), FALSE);
+    g_return_val_if_fail(xml != NULL, FALSE);
+    g_return_val_if_fail(ns != NULL, FALSE);
+    g_return_val_if_fail(ns_uri != NULL, FALSE);
+    g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
+
+    metadata_node = gvir_config_domain_get_metadata_node(domain, TRUE);
+
+    node = gvir_config_xml_parse(xml, NULL, error);
+    if (error != NULL && *error != NULL)
+        return FALSE;
+
+    namespace = xmlNewNs(node, (xmlChar *)ns_uri, (xmlChar *)ns);
+    set_namespace_on_tree(node, namespace);
+    doc = node->doc;
+
+    old_node = gvir_config_domain_get_custom_xml_node(domain, ns_uri);
+    if (old_node != NULL)
+        xmlReplaceNode(old_node, node);
+    else {
+        xmlUnlinkNode(node);
+        xmlAddChild(metadata_node, node);
+    }
+
+    xmlFreeDoc(doc);
+
+    return TRUE;
+}
+
+gchar *gvir_config_domain_get_custom_xml(GVirConfigDomain *domain,
+                                         const gchar *ns_uri,
+                                         GError **error)
+{
+    xmlNodePtr metadata_node, node;
+    xmlBufferPtr xmlbuf;
+    gchar *xml = NULL;
+
+    g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN(domain), NULL);
+
+    metadata_node = gvir_config_domain_get_metadata_node(domain, FALSE);
+    if (metadata_node == NULL)
+        return NULL;
+
+    node = gvir_config_domain_get_custom_xml_node(domain, ns_uri);
+    if (node == NULL)
+        return NULL;
+
+    xmlbuf = xmlBufferCreate();
+    if (xmlNodeDump(xmlbuf, metadata_node->doc, metadata_node, 0, 0) < 0)
+        gvir_config_set_error (error,
+                               GVIR_CONFIG_OBJECT_ERROR,
+                               0,
+                               "Failed to convert custom node '%s' to string",
+                               node->name);
+    else
+        xml = g_strndup((gchar *)xmlBufferContent(xmlbuf), xmlBufferLength(xmlbuf));
+
+    xmlBufferFree(xmlbuf);
+
+    return xml;
+}
diff --git a/libvirt-gconfig/libvirt-gconfig-domain.h b/libvirt-gconfig/libvirt-gconfig-domain.h
index 6cdaec9..96ded07 100644
--- a/libvirt-gconfig/libvirt-gconfig-domain.h
+++ b/libvirt-gconfig/libvirt-gconfig-domain.h
@@ -126,6 +126,14 @@ GList *gvir_config_domain_get_devices(GVirConfigDomain *domain);
 void gvir_config_domain_set_lifecycle(GVirConfigDomain *domain,
                                       GVirConfigDomainLifecycleEvent event,
                                       GVirConfigDomainLifecycleAction action);
+gboolean gvir_config_domain_set_custom_xml(GVirConfigDomain *domain,
+                                           const gchar *xml,
+                                           const gchar *ns,
+                                           const gchar *ns_uri,
+                                           GError **error);
+gchar *gvir_config_domain_get_custom_xml(GVirConfigDomain *domain,
+                                         const gchar *ns_uri,
+                                           GError **error);
 
 G_END_DECLS
 
diff --git a/libvirt-gconfig/libvirt-gconfig-helpers.c b/libvirt-gconfig/libvirt-gconfig-helpers.c
index c406a49..140a4a0 100644
--- a/libvirt-gconfig/libvirt-gconfig-helpers.c
+++ b/libvirt-gconfig/libvirt-gconfig-helpers.c
@@ -148,7 +148,9 @@ gvir_config_xml_parse(const char *xml, const char *root_node, GError **err)
                                       "Unable to parse configuration");
         return NULL;
     }
-    if ((!doc->children) || (strcmp((char *)doc->children->name, root_node) != 0)) {
+    if ((!doc->children) ||
+        (root_node != NULL &&
+         (strcmp((char *)doc->children->name, root_node) != 0))) {
         g_set_error(err,
                     GVIR_CONFIG_OBJECT_ERROR,
                     0,
diff --git a/libvirt-gconfig/libvirt-gconfig.sym b/libvirt-gconfig/libvirt-gconfig.sym
index 88aef57..ab2c7bf 100644
--- a/libvirt-gconfig/libvirt-gconfig.sym
+++ b/libvirt-gconfig/libvirt-gconfig.sym
@@ -14,6 +14,8 @@ LIBVIRT_GCONFIG_0.0.4 {
 	gvir_config_domain_new;
 	gvir_config_domain_new_from_xml;
 	gvir_config_domain_set_clock;
+	gvir_config_domain_set_custom_xml;
+	gvir_config_domain_get_custom_xml;
 	gvir_config_domain_get_description;
 	gvir_config_domain_set_description;
 	gvir_config_domain_get_devices;
-- 
1.7.7.5




More information about the libvir-list mailing list