With the current code, we can only create a custom XML that looks like:
<metadata>
<boxes:gnome-boxes
xmlns:boxes="https://wiki.gnome.org/Apps/Boxes">
<os-state>installed</os-state>
<
media-id>http://centos.org/centos/7.0:0</media-id>
<media>/home/fidencio/Downloads/CentOS-7-x86_64-DVD-1804.iso</media>
</boxes:gnome-boxes>
</metadata>
Although it works well for some use cases, there are use cases where
we'd like to have something a bit more complex libosinfo or nova
examples:
<metadata>
<libosinfo:libosinfo
xmlns:libosinfo="http://libosinfo.org/xmlns/libvirt/domain/1.0"...
<libosinfo:os
id="http://fedoraproject.org/fedora/17"/>
</libosinfo:libosinfo>
<nova:instance
xmlns:nova="http://openstack.org/nova/instance/1">
<nova:flavor name="m1.small">
<nova:memory>512</nova:memory>
<nova:disk>10</nova:disk>
</nova:flavor>
</nova:instance>
</metadata>
And for the latter case we'd have to go through the node's children and
also set the namespace for each children.
Signed-off-by: Fabiano FidĂȘncio <fidencio(a)redhat.com>
---
libvirt-gconfig/libvirt-gconfig-domain.c | 2 +-
.../libvirt-gconfig-object-private.h | 3 +-
libvirt-gconfig/libvirt-gconfig-object.c | 51 +++++++++++++++----
3 files changed, 44 insertions(+), 12 deletions(-)
diff --git a/libvirt-gconfig/libvirt-gconfig-domain.c
b/libvirt-gconfig/libvirt-gconfig-domain.c
index 4fbbe67..a99f9ef 100644
--- a/libvirt-gconfig/libvirt-gconfig-domain.c
+++ b/libvirt-gconfig/libvirt-gconfig-domain.c
@@ -806,7 +806,7 @@ gboolean gvir_config_domain_set_custom_xml(GVirConfigDomain *domain,
return FALSE;
}
- gvir_config_object_set_namespace(custom_xml, ns, ns_uri);
+ gvir_config_object_set_namespace(custom_xml, ns, ns_uri, FALSE);
gvir_config_object_delete_children(metadata, NULL, ns_uri);
gvir_config_object_attach_add(metadata, custom_xml);
diff --git a/libvirt-gconfig/libvirt-gconfig-object-private.h
b/libvirt-gconfig/libvirt-gconfig-object-private.h
index 7a0d21f..02c704e 100644
--- a/libvirt-gconfig/libvirt-gconfig-object-private.h
+++ b/libvirt-gconfig/libvirt-gconfig-object-private.h
@@ -111,7 +111,8 @@ void gvir_config_object_foreach_child(GVirConfigObject *object,
gpointer opaque);
gboolean gvir_config_object_set_namespace(GVirConfigObject *object,
const char *ns,
- const char *ns_uri);
+ const char *ns_uri,
+ gboolean ns_children);
GVirConfigObject *gvir_config_object_get_child(GVirConfigObject *object,
const gchar *child_name);
GVirConfigObject *gvir_config_object_get_child_with_type(GVirConfigObject *object,
diff --git a/libvirt-gconfig/libvirt-gconfig-object.c
b/libvirt-gconfig/libvirt-gconfig-object.c
index fffbd21..eb8763e 100644
--- a/libvirt-gconfig/libvirt-gconfig-object.c
+++ b/libvirt-gconfig/libvirt-gconfig-object.c
@@ -928,26 +928,57 @@ gvir_config_object_remove_attribute(GVirConfigObject *object,
} while (status == 0);
}
-G_GNUC_INTERNAL gboolean
-gvir_config_object_set_namespace(GVirConfigObject *object, const char *ns,
- const char *ns_uri)
+static gboolean
+gvir_config_object_set_xmlnode_namespace(xmlNodePtr node, const char *ns,
+ const char *ns_uri)
{
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);
+ namespace = xmlNewNs(node, (xmlChar *)ns_uri, (xmlChar *)ns);
if (namespace == NULL)
return FALSE;
- xmlSetNs(object->priv->node, namespace);
+ xmlSetNs(node, namespace);
+ return TRUE;
+}
+
+static gboolean
+gvir_config_object_set_namespace_recursively(xmlNodePtr node,
+ const char *ns,
+ const char *ns_uri)
+{
+ xmlNodePtr n;
+
+ for (n = node; n != NULL; n = n->next) {
+ if (n->type == XML_ELEMENT_NODE) {
+ if (!gvir_config_object_set_xmlnode_namespace(n, ns, ns_uri))
+ return FALSE;
+ }
+
+ if (!gvir_config_object_set_namespace_recursively(n->children, ns, NULL))
+ return FALSE;
+ }
return TRUE;
}
+G_GNUC_INTERNAL gboolean
+gvir_config_object_set_namespace(GVirConfigObject *object, const char *ns,
+ const char *ns_uri, gboolean ns_children)
+{
+ 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);
+
+ if (!ns_children) {
+ return gvir_config_object_set_xmlnode_namespace(object->priv->node,
+ ns, ns_uri);
+ }
+
+ return gvir_config_object_set_namespace_recursively(object->priv->node,
+ ns, ns_uri);
+}
+
G_GNUC_INTERNAL GVirConfigObject *
gvir_config_object_get_child_with_type(GVirConfigObject *object,
const gchar *child_name,
--
2.19.0