[libvirt] [glib PATCH 1/2] object: Also add the ns to the node's children

Fabiano Fidêncio fidencio at redhat.com
Wed Oct 3 11:59:38 UTC 2018


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 at 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




More information about the libvir-list mailing list