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

Christophe Fergeau cfergeau at redhat.com
Mon Jan 23 17:19:28 UTC 2012


Based on a patch from Zeeshan Ali (Khattak) <zeeshanak at gnome.org>
---
 libvirt-gconfig/libvirt-gconfig-domain.c          |   60 +++++++++++++++++++++
 libvirt-gconfig/libvirt-gconfig-domain.h          |    7 +++
 libvirt-gconfig/libvirt-gconfig-helpers-private.h |    1 +
 libvirt-gconfig/libvirt-gconfig-helpers.c         |   23 ++++++++-
 libvirt-gconfig/libvirt-gconfig-object-private.h  |    4 ++
 libvirt-gconfig/libvirt-gconfig-object.c          |   32 +++++++++++
 libvirt-gconfig/libvirt-gconfig.sym               |    2 +
 7 files changed, 128 insertions(+), 1 deletions(-)

diff --git a/libvirt-gconfig/libvirt-gconfig-domain.c b/libvirt-gconfig/libvirt-gconfig-domain.c
index 61af625..d943099 100644
--- a/libvirt-gconfig/libvirt-gconfig-domain.c
+++ b/libvirt-gconfig/libvirt-gconfig-domain.c
@@ -449,3 +449,63 @@ GList *gvir_config_domain_get_devices(GVirConfigDomain *domain)
 
     return data.devices;
 }
+
+gboolean gvir_config_domain_set_custom_xml(GVirConfigDomain *domain,
+                                           const gchar *xml,
+                                           const gchar *ns,
+                                           const gchar *ns_uri,
+                                           GError **error)
+{
+    GVirConfigObject *metadata;
+    GVirConfigObject *custom_xml;
+
+    g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN(domain), FALSE);
+    g_return_val_if_fail(xml != NULL, FALSE);
+    g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
+
+    metadata = gvir_config_object_add_child(GVIR_CONFIG_OBJECT(domain), "metadata");
+
+    custom_xml = gvir_config_object_new_from_xml(GVIR_CONFIG_TYPE_OBJECT, NULL, NULL, xml, error);
+    if (error != NULL && *error != NULL)
+        return FALSE;
+
+    gvir_config_object_set_namespace(custom_xml, ns, ns_uri, TRUE);
+
+    gvir_config_object_attach_replace(metadata, custom_xml);
+
+    return TRUE;
+}
+
+struct LookupNamespacedNodeData {
+    const char *ns_uri;
+    xmlNodePtr node;
+};
+
+static gboolean lookup_namespaced_node(xmlNodePtr node, gpointer opaque)
+{
+    struct LookupNamespacedNodeData* data = opaque;
+
+    if (node->ns == NULL)
+        return TRUE;
+
+    if (g_strcmp0((char *)node->ns->href, data->ns_uri) == 0) {
+        data->node = node;
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+gchar *gvir_config_domain_get_custom_xml(GVirConfigDomain *domain,
+                                         const gchar *ns_uri)
+{
+    struct LookupNamespacedNodeData data = { NULL, NULL };
+
+    g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN(domain), NULL);
+    g_return_val_if_fail(ns_uri != NULL, NULL);
+
+    data.ns_uri = ns_uri;
+    gvir_config_object_foreach_child(GVIR_CONFIG_OBJECT(domain), "metadata",
+                                     lookup_namespaced_node, &data);
+    return gvir_config_xml_node_to_string(data.node);
+}
diff --git a/libvirt-gconfig/libvirt-gconfig-domain.h b/libvirt-gconfig/libvirt-gconfig-domain.h
index 6cdaec9..769d2f0 100644
--- a/libvirt-gconfig/libvirt-gconfig-domain.h
+++ b/libvirt-gconfig/libvirt-gconfig-domain.h
@@ -126,6 +126,13 @@ 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);
 
 G_END_DECLS
 
diff --git a/libvirt-gconfig/libvirt-gconfig-helpers-private.h b/libvirt-gconfig/libvirt-gconfig-helpers-private.h
index 96ec02e..514aeb0 100644
--- a/libvirt-gconfig/libvirt-gconfig-helpers-private.h
+++ b/libvirt-gconfig/libvirt-gconfig-helpers-private.h
@@ -56,6 +56,7 @@ char *gvir_config_xml_get_child_element_content_glib (xmlNode    *node,
                                                       const char *child_name);
 xmlChar *gvir_config_xml_get_attribute_content(xmlNodePtr node,
                                                const char *attr_name);
+char *gvir_config_xml_node_to_string(xmlNodePtr node);
 char *gvir_config_xml_get_attribute_content_glib(xmlNodePtr node,
                                                  const char *attr_name);
 const char *gvir_config_genum_get_nick (GType enum_type, gint value);
diff --git a/libvirt-gconfig/libvirt-gconfig-helpers.c b/libvirt-gconfig/libvirt-gconfig-helpers.c
index c406a49..6500439 100644
--- a/libvirt-gconfig/libvirt-gconfig-helpers.c
+++ b/libvirt-gconfig/libvirt-gconfig-helpers.c
@@ -148,7 +148,8 @@ 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) ||
+         (g_strcmp0((char *)doc->children->name, root_node) != 0)) {
         g_set_error(err,
                     GVIR_CONFIG_OBJECT_ERROR,
                     0,
@@ -306,3 +307,23 @@ gvir_config_genum_get_value (GType enum_type, const char *nick,
 
     g_return_val_if_reached(default_value);
 }
+
+G_GNUC_INTERNAL char *
+gvir_config_xml_node_to_string(xmlNodePtr node)
+{
+    xmlBufferPtr xmlbuf;
+    char *xml;
+
+    if (node == NULL)
+        return NULL;
+
+    xmlbuf = xmlBufferCreate();
+    if (xmlNodeDump(xmlbuf, node->doc, node, 0, 0) < 0)
+        return NULL;
+    else
+        xml = g_strndup((gchar *)xmlBufferContent(xmlbuf), xmlBufferLength(xmlbuf));
+
+    xmlBufferFree(xmlbuf);
+
+    return xml;
+}
diff --git a/libvirt-gconfig/libvirt-gconfig-object-private.h b/libvirt-gconfig/libvirt-gconfig-object-private.h
index 781e1a3..8fc9a08 100644
--- a/libvirt-gconfig/libvirt-gconfig-object-private.h
+++ b/libvirt-gconfig/libvirt-gconfig-object-private.h
@@ -90,6 +90,10 @@ void gvir_config_object_foreach_child(GVirConfigObject *object,
                                       const char *parent_name,
                                       GVirConfigXmlNodeIterator iter_func,
                                       gpointer opaque);
+gboolean gvir_config_object_set_namespace(GVirConfigObject *object,
+                                          const char *ns,
+                                          const char *ns_uri,
+                                          gboolean recursive);
 
 G_END_DECLS
 
diff --git a/libvirt-gconfig/libvirt-gconfig-object.c b/libvirt-gconfig/libvirt-gconfig-object.c
index 2e28208..5449bd6 100644
--- a/libvirt-gconfig/libvirt-gconfig-object.c
+++ b/libvirt-gconfig/libvirt-gconfig-object.c
@@ -846,3 +846,35 @@ gvir_config_object_remove_attribute(GVirConfigObject *object,
         status = xmlUnsetProp(object->priv->node, (xmlChar *)attr_name);
     } while (status == 0);
 }
+
+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);
+}
+
+G_GNUC_INTERNAL gboolean
+gvir_config_object_set_namespace(GVirConfigObject *object, const char *ns,
+                                 const char *ns_uri, gboolean recursive)
+{
+    xmlNsPtr namespace;
+
+    g_return_val_if_fail(GVIR_CONFIG_IS_OBJECT(object), FALSE);
+    g_return_val_if_fail(ns != NULL, FALSE);
+    g_return_val_if_fail(ns_uri != NULL, FALSE);
+
+    namespace = xmlNewNs(object->priv->node,
+                         (xmlChar *)ns_uri, (xmlChar *)ns);
+    if (namespace == NULL)
+        return FALSE;
+    if (recursive) {
+        set_namespace_on_tree(object->priv->node, namespace);
+    } else {
+        xmlSetNs(object->priv->node, namespace);
+    }
+    return TRUE;
+}
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