[libvirt] [libvirt-glib 1/7] Fix gvir_config_object_new_from_xml error reporting

It's currently failing to report parsing errors if the passed in error is NULL. --- libvirt-gconfig/libvirt-gconfig-object.c | 7 +++++-- 1 files changed, 5 insertions(+), 2 deletions(-) diff --git a/libvirt-gconfig/libvirt-gconfig-object.c b/libvirt-gconfig/libvirt-gconfig-object.c index 2e28208..7e3cb88 100644 --- a/libvirt-gconfig/libvirt-gconfig-object.c +++ b/libvirt-gconfig/libvirt-gconfig-object.c @@ -636,10 +636,13 @@ GVirConfigObject *gvir_config_object_new_from_xml(GType type, GVirConfigObject *object; GVirConfigXmlDoc *doc; xmlNodePtr node; + GError *tmp_error = NULL; - node = gvir_config_xml_parse(xml, root_name, error); - if ((error != NULL) && (*error != NULL)) + node = gvir_config_xml_parse(xml, root_name, &tmp_error); + if (tmp_error != NULL) { + g_propagate_error(error, tmp_error); return NULL; + } doc = gvir_config_xml_doc_new(node->doc); object = GVIR_CONFIG_OBJECT(g_object_new(type, "doc", doc, -- 1.7.7.6

It's only used to make some sanity checks on what was just parsed, so allowing NULL root_node is fine. --- libvirt-gconfig/libvirt-gconfig-helpers.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/libvirt-gconfig/libvirt-gconfig-helpers.c b/libvirt-gconfig/libvirt-gconfig-helpers.c index fecf3eb..a9aaa0b 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) || + ((root_node != NULL) && g_strcmp0((char *)doc->children->name, root_node) != 0)) { g_set_error(err, GVIR_CONFIG_OBJECT_ERROR, 0, -- 1.7.7.6

On Mon, Feb 06, 2012 at 12:56:12PM +0100, Christophe Fergeau wrote:
It's only used to make some sanity checks on what was just parsed, so allowing NULL root_node is fine. --- libvirt-gconfig/libvirt-gconfig-helpers.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/libvirt-gconfig/libvirt-gconfig-helpers.c b/libvirt-gconfig/libvirt-gconfig-helpers.c index fecf3eb..a9aaa0b 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) || + ((root_node != NULL) && g_strcmp0((char *)doc->children->name, root_node) != 0)) { g_set_error(err, GVIR_CONFIG_OBJECT_ERROR, 0,
ACK Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

--- libvirt-gconfig/libvirt-gconfig-helpers-private.h | 1 + libvirt-gconfig/libvirt-gconfig-helpers.c | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 0 deletions(-) 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 a9aaa0b..c34a312 100644 --- a/libvirt-gconfig/libvirt-gconfig-helpers.c +++ b/libvirt-gconfig/libvirt-gconfig-helpers.c @@ -308,3 +308,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; +} -- 1.7.7.6

On Mon, Feb 06, 2012 at 12:56:13PM +0100, Christophe Fergeau wrote:
--- libvirt-gconfig/libvirt-gconfig-helpers-private.h | 1 + libvirt-gconfig/libvirt-gconfig-helpers.c | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 0 deletions(-)
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 a9aaa0b..c34a312 100644 --- a/libvirt-gconfig/libvirt-gconfig-helpers.c +++ b/libvirt-gconfig/libvirt-gconfig-helpers.c @@ -308,3 +308,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; +}
In gvir_config_object_to_xml() we pass '1' for the 'format' argument to get pretty-printed XML. Perhaps we should do the same here too ? ACK either way Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

On Mon, Feb 06, 2012 at 12:02:23PM +0000, Daniel P. Berrange wrote:
In gvir_config_object_to_xml() we pass '1' for the 'format' argument to get pretty-printed XML. Perhaps we should do the same here too ?
Sure, makes sense to be consistent. Actually, we could even go with this followup patch: diff --git a/libvirt-gconfig/libvirt-gconfig-object.c b/libvirt-gconfig/libvirt-gconfig-object.c index a42b36c..662b8ed 100644 --- a/libvirt-gconfig/libvirt-gconfig-object.c +++ b/libvirt-gconfig/libvirt-gconfig-object.c @@ -256,21 +256,7 @@ void gvir_config_object_validate(GVirConfigObject *config, gchar *gvir_config_object_to_xml(GVirConfigObject *config) { - xmlChar *doc; - int size; - xmlNodePtr node; - gchar *output_doc; - - node = gvir_config_object_get_xml_node(config); - if (node == NULL) - return NULL; - - xmlDocDumpFormatMemory(node->doc, &doc, &size, 1); - - output_doc = g_strdup((gchar *)doc); - xmlFree(doc); - - return output_doc; + return gvir_config_xml_node_to_string(config->priv->node); } const gchar *gvir_config_object_get_schema(GVirConfigObject *config) Christophe

On Mon, Feb 06, 2012 at 02:08:34PM +0100, Christophe Fergeau wrote:
On Mon, Feb 06, 2012 at 12:02:23PM +0000, Daniel P. Berrange wrote:
In gvir_config_object_to_xml() we pass '1' for the 'format' argument to get pretty-printed XML. Perhaps we should do the same here too ?
Sure, makes sense to be consistent. Actually, we could even go with this followup patch:
diff --git a/libvirt-gconfig/libvirt-gconfig-object.c b/libvirt-gconfig/libvirt-gconfig-object.c index a42b36c..662b8ed 100644 --- a/libvirt-gconfig/libvirt-gconfig-object.c +++ b/libvirt-gconfig/libvirt-gconfig-object.c @@ -256,21 +256,7 @@ void gvir_config_object_validate(GVirConfigObject *config,
gchar *gvir_config_object_to_xml(GVirConfigObject *config) { - xmlChar *doc; - int size; - xmlNodePtr node; - gchar *output_doc; - - node = gvir_config_object_get_xml_node(config); - if (node == NULL) - return NULL; - - xmlDocDumpFormatMemory(node->doc, &doc, &size, 1); - - output_doc = g_strdup((gchar *)doc); - xmlFree(doc); - - return output_doc; + return gvir_config_xml_node_to_string(config->priv->node); }
const gchar *gvir_config_object_get_schema(GVirConfigObject *config)
ACK, looks good to me Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

These functions now take an additional argument corresponding to a namespace href. It's optional and can be NULL when namespaces should be ignored. The 'child_name' argument can now be NULL in order to remove all nodes belonging to a given namespace. --- libvirt-gconfig/libvirt-gconfig-domain-disk.c | 2 +- libvirt-gconfig/libvirt-gconfig-domain-filesys.c | 2 +- libvirt-gconfig/libvirt-gconfig-object-private.h | 7 ++- libvirt-gconfig/libvirt-gconfig-object.c | 50 ++++++++++++++++------ 4 files changed, 43 insertions(+), 18 deletions(-) diff --git a/libvirt-gconfig/libvirt-gconfig-domain-disk.c b/libvirt-gconfig/libvirt-gconfig-domain-disk.c index fb4e2b4..b2861e4 100644 --- a/libvirt-gconfig/libvirt-gconfig-domain-disk.c +++ b/libvirt-gconfig/libvirt-gconfig-domain-disk.c @@ -301,5 +301,5 @@ gvir_config_domain_disk_set_readonly(GVirConfigDomainDisk *disk, GVirConfigObject *node = gvir_config_object_replace_child(GVIR_CONFIG_OBJECT(disk), "readonly"); g_object_unref(node); } else - gvir_config_object_delete_child(GVIR_CONFIG_OBJECT(disk), "readonly"); + gvir_config_object_delete_child(GVIR_CONFIG_OBJECT(disk), "readonly", NULL); } diff --git a/libvirt-gconfig/libvirt-gconfig-domain-filesys.c b/libvirt-gconfig/libvirt-gconfig-domain-filesys.c index 3eb96f6..904a7a3 100644 --- a/libvirt-gconfig/libvirt-gconfig-domain-filesys.c +++ b/libvirt-gconfig/libvirt-gconfig-domain-filesys.c @@ -156,6 +156,6 @@ void gvir_config_domain_filesys_set_readonly(GVirConfigDomainFilesys *filesys, GVirConfigObject *node = gvir_config_object_replace_child(GVIR_CONFIG_OBJECT(filesys), "readonly"); g_object_unref(node); } else { - gvir_config_object_delete_child(GVIR_CONFIG_OBJECT(filesys), "readonly"); + gvir_config_object_delete_child(GVIR_CONFIG_OBJECT(filesys), "readonly", NULL); } } diff --git a/libvirt-gconfig/libvirt-gconfig-object-private.h b/libvirt-gconfig/libvirt-gconfig-object-private.h index 781e1a3..afd28f0 100644 --- a/libvirt-gconfig/libvirt-gconfig-object-private.h +++ b/libvirt-gconfig/libvirt-gconfig-object-private.h @@ -71,8 +71,11 @@ void gvir_config_object_replace_child_with_attribute(GVirConfigObject *object, const char *attr_name, const char *attr_value); void gvir_config_object_delete_child(GVirConfigObject *object, - const char *child_name); -void gvir_config_object_delete_children(GVirConfigObject *object, const char *child_name); + const char *child_name, + const char *ns_href); +void gvir_config_object_delete_children(GVirConfigObject *object, + const char *child_name, + const char *ns_href); void gvir_config_object_set_child(GVirConfigObject *object, xmlNodePtr child); diff --git a/libvirt-gconfig/libvirt-gconfig-object.c b/libvirt-gconfig/libvirt-gconfig-object.c index 7e3cb88..9d99faf 100644 --- a/libvirt-gconfig/libvirt-gconfig-object.c +++ b/libvirt-gconfig/libvirt-gconfig-object.c @@ -465,16 +465,29 @@ gvir_config_object_replace_child_with_attribute(GVirConfigObject *object, g_object_unref(G_OBJECT(child)); } -static gboolean maybe_unlink_node(xmlNodePtr node, const char *name) +struct NodeMatch { + const char *name; + const char *ns; +}; + +static gboolean maybe_unlink_node(xmlNodePtr node, void *opaque) { - if (g_strcmp0((char *)node->name, name) == 0) { + gboolean unlink = TRUE; + struct NodeMatch *match = (struct NodeMatch *)opaque; + + if (match->ns != NULL) { + unlink = unlink && (g_strcmp0(match->ns, (char *)node->ns->href) == 0); + } + + if (match->name != NULL) { + unlink = unlink && (g_strcmp0(match->name, (char *)node->name) == 0); + } + if (unlink) { xmlUnlinkNode(node); xmlFreeNode(node); - - return TRUE; } - return FALSE; + return unlink; } static gboolean remove_oneshot(xmlNodePtr node, gpointer opaque) @@ -484,13 +497,16 @@ static gboolean remove_oneshot(xmlNodePtr node, gpointer opaque) G_GNUC_INTERNAL void gvir_config_object_delete_child(GVirConfigObject *object, - const char *child_name) + const char *child_name, + const char *ns_href) { + struct NodeMatch match; + g_return_if_fail(GVIR_CONFIG_IS_OBJECT(object)); - g_return_if_fail(child_name != NULL); - gvir_config_object_foreach_child(object, NULL, remove_oneshot, - (gpointer)child_name); + match.name = child_name; + match.ns = ns_href; + gvir_config_object_foreach_child(object, NULL, remove_oneshot, &match); } static gboolean remove_always(xmlNodePtr node, gpointer opaque) @@ -501,13 +517,18 @@ static gboolean remove_always(xmlNodePtr node, gpointer opaque) } G_GNUC_INTERNAL void -gvir_config_object_delete_children(GVirConfigObject *object, const char *child_name) +gvir_config_object_delete_children(GVirConfigObject *object, + const char *child_name, + const char *ns_href) { + struct NodeMatch match; + g_return_if_fail(GVIR_CONFIG_IS_OBJECT(object)); - g_return_if_fail(child_name != NULL); - gvir_config_object_foreach_child(object, NULL, remove_always, - (gpointer)child_name); + match.name = child_name; + match.ns = ns_href; + + gvir_config_object_foreach_child(object, NULL, remove_always, &match); } G_GNUC_INTERNAL void @@ -814,7 +835,8 @@ gvir_config_object_attach(GVirConfigObject *parent, GVirConfigObject *child, gbo if (replace) { gvir_config_object_delete_children(parent, - (char *)child->priv->node->name); + (char *)child->priv->node->name, + NULL); } xmlUnlinkNode(child->priv->node); xmlAddChild(parent->priv->node, child->priv->node); -- 1.7.7.6

On Mon, Feb 06, 2012 at 12:56:14PM +0100, Christophe Fergeau wrote:
These functions now take an additional argument corresponding to a namespace href. It's optional and can be NULL when namespaces should be ignored. The 'child_name' argument can now be NULL in order to remove all nodes belonging to a given namespace. --- libvirt-gconfig/libvirt-gconfig-domain-disk.c | 2 +- libvirt-gconfig/libvirt-gconfig-domain-filesys.c | 2 +- libvirt-gconfig/libvirt-gconfig-object-private.h | 7 ++- libvirt-gconfig/libvirt-gconfig-object.c | 50 ++++++++++++++++------ 4 files changed, 43 insertions(+), 18 deletions(-)
ACK Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

--- libvirt-gconfig/libvirt-gconfig-object-private.h | 3 +++ libvirt-gconfig/libvirt-gconfig-object.c | 20 ++++++++++++++++++++ 2 files changed, 23 insertions(+), 0 deletions(-) diff --git a/libvirt-gconfig/libvirt-gconfig-object-private.h b/libvirt-gconfig/libvirt-gconfig-object-private.h index afd28f0..41cbfe8 100644 --- a/libvirt-gconfig/libvirt-gconfig-object-private.h +++ b/libvirt-gconfig/libvirt-gconfig-object-private.h @@ -93,6 +93,9 @@ 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); G_END_DECLS diff --git a/libvirt-gconfig/libvirt-gconfig-object.c b/libvirt-gconfig/libvirt-gconfig-object.c index 9d99faf..a42b36c 100644 --- a/libvirt-gconfig/libvirt-gconfig-object.c +++ b/libvirt-gconfig/libvirt-gconfig-object.c @@ -871,3 +871,23 @@ gvir_config_object_remove_attribute(GVirConfigObject *object, status = xmlUnsetProp(object->priv->node, (xmlChar *)attr_name); } while (status == 0); } + +G_GNUC_INTERNAL gboolean +gvir_config_object_set_namespace(GVirConfigObject *object, 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); + if (namespace == NULL) + return FALSE; + + xmlSetNs(object->priv->node, namespace); + + return TRUE; +} -- 1.7.7.6

On Mon, Feb 06, 2012 at 12:56:15PM +0100, Christophe Fergeau wrote:
--- libvirt-gconfig/libvirt-gconfig-object-private.h | 3 +++ libvirt-gconfig/libvirt-gconfig-object.c | 20 ++++++++++++++++++++ 2 files changed, 23 insertions(+), 0 deletions(-)
diff --git a/libvirt-gconfig/libvirt-gconfig-object-private.h b/libvirt-gconfig/libvirt-gconfig-object-private.h index afd28f0..41cbfe8 100644 --- a/libvirt-gconfig/libvirt-gconfig-object-private.h +++ b/libvirt-gconfig/libvirt-gconfig-object-private.h @@ -93,6 +93,9 @@ 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);
G_END_DECLS
diff --git a/libvirt-gconfig/libvirt-gconfig-object.c b/libvirt-gconfig/libvirt-gconfig-object.c index 9d99faf..a42b36c 100644 --- a/libvirt-gconfig/libvirt-gconfig-object.c +++ b/libvirt-gconfig/libvirt-gconfig-object.c @@ -871,3 +871,23 @@ gvir_config_object_remove_attribute(GVirConfigObject *object, status = xmlUnsetProp(object->priv->node, (xmlChar *)attr_name); } while (status == 0); } + +G_GNUC_INTERNAL gboolean +gvir_config_object_set_namespace(GVirConfigObject *object, 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); + if (namespace == NULL) + return FALSE; + + xmlSetNs(object->priv->node, namespace); + + return TRUE; +}
ACK Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

Based on a patch from Zeeshan Ali (Khattak) <zeeshanak@gnome.org> --- libvirt-gconfig/libvirt-gconfig-domain.c | 67 ++++++++++++++++++++++++++++++ libvirt-gconfig/libvirt-gconfig-domain.h | 7 +++ libvirt-gconfig/libvirt-gconfig.sym | 2 + 3 files changed, 76 insertions(+), 0 deletions(-) diff --git a/libvirt-gconfig/libvirt-gconfig-domain.c b/libvirt-gconfig/libvirt-gconfig-domain.c index 61af625..d7ac4c6 100644 --- a/libvirt-gconfig/libvirt-gconfig-domain.c +++ b/libvirt-gconfig/libvirt-gconfig-domain.c @@ -449,3 +449,70 @@ 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 (custom_xml == NULL) { + g_assert_not_reached(); + g_object_unref(G_OBJECT(metadata)); + return FALSE; + } + + gvir_config_object_set_namespace(custom_xml, ns, ns_uri); + + gvir_config_object_delete_children(metadata, NULL, ns_uri); + gvir_config_object_attach_add(metadata, custom_xml); + g_object_unref(G_OBJECT(metadata)); + + 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.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.6

On Mon, Feb 06, 2012 at 12:56:16PM +0100, Christophe Fergeau wrote:
Based on a patch from Zeeshan Ali (Khattak) <zeeshanak@gnome.org> --- libvirt-gconfig/libvirt-gconfig-domain.c | 67 ++++++++++++++++++++++++++++++ libvirt-gconfig/libvirt-gconfig-domain.h | 7 +++ libvirt-gconfig/libvirt-gconfig.sym | 2 + 3 files changed, 76 insertions(+), 0 deletions(-)
ACK Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

--- libvirt-gconfig/tests/test-domain-create.c | 7 +++++++ 1 files changed, 7 insertions(+), 0 deletions(-) diff --git a/libvirt-gconfig/tests/test-domain-create.c b/libvirt-gconfig/tests/test-domain-create.c index 14636e5..1610587 100644 --- a/libvirt-gconfig/tests/test-domain-create.c +++ b/libvirt-gconfig/tests/test-domain-create.c @@ -172,6 +172,13 @@ int main(int argc, char **argv) g_list_free(devices); devices = NULL; + gvir_config_domain_set_custom_xml(domain, "<foo/>", "ns", "http://foo", NULL); + gvir_config_domain_set_custom_xml(domain, "<foo/>", "nsbar", "http://bar", NULL); + gvir_config_domain_set_custom_xml(domain, "<foo/>", "ns", "http://bar", NULL); + gvir_config_domain_set_custom_xml(domain, "<bar/>", "ns", "http://foo", NULL); + + g_assert(g_strcmp0(gvir_config_domain_get_custom_xml(domain, "http://foo"), "<ns:bar xmlns:ns=\"http://foo\"/>") == 0); + g_assert(g_strcmp0(gvir_config_domain_get_custom_xml(domain, "http://bar"), "<ns:foo xmlns:ns=\"http://bar\"/>") == 0); xml = gvir_config_object_to_xml(GVIR_CONFIG_OBJECT(domain)); g_print("%s\n\n", xml); -- 1.7.7.6

On Mon, Feb 06, 2012 at 12:56:17PM +0100, Christophe Fergeau wrote:
--- libvirt-gconfig/tests/test-domain-create.c | 7 +++++++ 1 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/libvirt-gconfig/tests/test-domain-create.c b/libvirt-gconfig/tests/test-domain-create.c index 14636e5..1610587 100644 --- a/libvirt-gconfig/tests/test-domain-create.c +++ b/libvirt-gconfig/tests/test-domain-create.c @@ -172,6 +172,13 @@ int main(int argc, char **argv) g_list_free(devices); devices = NULL;
+ gvir_config_domain_set_custom_xml(domain, "<foo/>", "ns", "http://foo", NULL); + gvir_config_domain_set_custom_xml(domain, "<foo/>", "nsbar", "http://bar", NULL); + gvir_config_domain_set_custom_xml(domain, "<foo/>", "ns", "http://bar", NULL); + gvir_config_domain_set_custom_xml(domain, "<bar/>", "ns", "http://foo", NULL); + + g_assert(g_strcmp0(gvir_config_domain_get_custom_xml(domain, "http://foo"), "<ns:bar xmlns:ns=\"http://foo\"/>") == 0); + g_assert(g_strcmp0(gvir_config_domain_get_custom_xml(domain, "http://bar"), "<ns:foo xmlns:ns=\"http://bar\"/>") == 0);
ACK Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

On Mon, Feb 06, 2012 at 12:56:11PM +0100, Christophe Fergeau wrote:
It's currently failing to report parsing errors if the passed in error is NULL. --- libvirt-gconfig/libvirt-gconfig-object.c | 7 +++++-- 1 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/libvirt-gconfig/libvirt-gconfig-object.c b/libvirt-gconfig/libvirt-gconfig-object.c index 2e28208..7e3cb88 100644 --- a/libvirt-gconfig/libvirt-gconfig-object.c +++ b/libvirt-gconfig/libvirt-gconfig-object.c @@ -636,10 +636,13 @@ GVirConfigObject *gvir_config_object_new_from_xml(GType type, GVirConfigObject *object; GVirConfigXmlDoc *doc; xmlNodePtr node; + GError *tmp_error = NULL;
- node = gvir_config_xml_parse(xml, root_name, error); - if ((error != NULL) && (*error != NULL)) + node = gvir_config_xml_parse(xml, root_name, &tmp_error); + if (tmp_error != NULL) { + g_propagate_error(error, tmp_error); return NULL; + } doc = gvir_config_xml_doc_new(node->doc); object = GVIR_CONFIG_OBJECT(g_object_new(type, "doc", doc,
ACK Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|
participants (2)
-
Christophe Fergeau
-
Daniel P. Berrange