From: "Zeeshan Ali (Khattak)" <zeeshanak(a)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