Browse Source

libgovirt package update

Signed-off-by: virtbuilder_pel7ppc64lebuilder0 <virtbuilder@powerel.org>
master
virtbuilder_pel7ppc64lebuilder0 5 years ago
parent
commit
f1e4dfa9f4
  1. 52
      SOURCES/0001-proxy-Fix-persistent-session-with-oVirt-3.6.patch
  2. 28
      SOURCES/0002-Force-use-of-v3-REST-API.patch
  3. 22
      SOURCES/0003-New-storage-format-added-in-oVirt-4.1.patch
  4. 35
      SOURCES/0004-proxy-Hold-reference-to-cancellable-object.patch
  5. 40
      SOURCES/0005-proxy-Check-if-operation-is-cancelled-before-disconn.patch
  6. 107
      SOURCES/0006-storage-domain-Factor-out-property-value-setting-fro.patch
  7. 89
      SOURCES/0007-storage-domain-use-explicit-initialization-of-struct.patch
  8. 325
      SOURCES/0008-storage-domain-Move-out-ovirt_resource_parse_xml-to-.patch
  9. 57
      SOURCES/0009-utils-Remove-unused-function-ovirt_rest_xml_node_get.patch
  10. 91
      SOURCES/0010-utils-Rename-ovirt_rest_xml_node_get_content_va-to-o.patch
  11. 65
      SOURCES/0011-utils-Retrieve-node-attributes-in-ovirt_resource_par.patch
  12. 26
      SOURCES/0012-utils-Support-G_TYPE_STRING-in-_set_property_value_f.patch
  13. 111
      SOURCES/0013-utils-Support-G_TYPE_STRV-in-_set_property_value_fro.patch
  14. 203
      SOURCES/0014-Introduce-auxiliary-function-ovirt_sub_collection_ne.patch
  15. 199
      SOURCES/0015-New-API-functions-to-enable-search-queries-of-collec.patch
  16. 85
      SOURCES/0016-Introduce-ovirt_resource_new-functions.patch
  17. 144
      SOURCES/0017-Use-ovirt_resource_new-functions-instead-of-g_initab.patch
  18. 135
      SOURCES/0018-Move-resource-type-definitions-to-ovirt-types.h.patch
  19. 515
      SOURCES/0019-Initial-support-for-hosts.patch
  20. 519
      SOURCES/0020-Initial-support-for-clusters.patch
  21. 452
      SOURCES/0021-Initial-support-for-data-centers.patch
  22. 195
      SOURCES/0022-vm-Introduce-ovirt_vm_get_host.patch
  23. 176
      SOURCES/0023-vm-Introduce-ovirt_vm_get_cluster.patch
  24. 95
      SOURCES/0024-host-Introduce-ovirt_host_get_cluster.patch
  25. 93
      SOURCES/0025-cluster-Introduce-ovirt_cluster_get_data_center.patch
  26. 93
      SOURCES/0026-storage-domain-Retrieve-data-center-ids.patch
  27. 26
      SOURCES/0027-Add-missing-include-in-govirt.h.patch
  28. 23
      SOURCES/0028-resource-Fix-ovirt_resource_rest_call_sync-return-va.patch
  29. 39
      SOURCES/0029-resource-Fix-ovirt_resource_rest_call_sync-crash-on-.patch
  30. 29
      SOURCES/0030-resource-Fix-ovirt_resource_init_from_xml_real-preco.patch
  31. 61
      SOURCES/0031-resource-Update-xml-node-in-ovirt_resource_init_from.patch
  32. 151
      SOURCES/0032-utils-Drop-type-member-from-OvirtXmlElement-struct.patch
  33. 39
      SOURCES/0033-utils-Support-G_TYPE_UINT-in-_set_property_value_fro.patch
  34. 28
      SOURCES/0034-utils-Improve-log-message-when-subnode-is-not-found.patch
  35. 92
      SOURCES/0035-utils-Factor-out-basic-value-type-setting-from-_set_.patch
  36. 54
      SOURCES/0036-utils-Get-enum-default-value-from-GParamSpec.patch
  37. 81
      SOURCES/0037-vm-Set-vm-state-property-using-OvirtXmlElement-struc.patch
  38. 189
      SOURCES/0038-vm-Set-values-of-OvirtVmDisplay-using-OvirtXmlElemen.patch
  39. 265
      SOURCES/0039-vm-display-Move-XML-parsing-from-ovirt-vm-xml.c-file.patch
  40. 97
      SOURCES/0040-vm-Set-ticket-expiry-using-OvirtXmlElement-struct.patch
  41. 38
      SOURCES/0041-test-govirt-Add-display-node-to-vm-XMLs.patch
  42. 65
      SOURCES/0042-proxy-Set-detailed-error-message-for-async-call.patch
  43. 107
      SOURCES/0043-cdrom-Set-file-property-using-OvirtXmlElement-struct.patch
  44. 30
      SOURCES/0044-proxy-Don-t-try-to-unref-NULL-root-node.patch
  45. 97
      SOURCES/0045-utils-Check-for-valid-data-before-calling-rest_xml_p.patch
  46. 146
      SOURCES/0046-Update-tests-certificates.patch
  47. 229
      SPECS/libgovirt.spec

52
SOURCES/0001-proxy-Fix-persistent-session-with-oVirt-3.6.patch

@ -0,0 +1,52 @@ @@ -0,0 +1,52 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Christophe Fergeau <cfergeau@redhat.com>
Date: Tue, 14 Jun 2016 14:38:07 +0200
Subject: [PATCH] proxy: Fix persistent session with oVirt 3.6

commit d3683c2 "proxy: Only set 'Prefer: persistent-auth' with
jsession-id" was working as expected when using the
OvirtProxy::jsession-id and OvirtProxy::sso-token properties.

However, when not using these properties and expecting the jsessionid to
be set as a cookie during a regular HTTP session, this was not working
properly as oVirt is not sending a jsessionid cookie when Prefer:
persistent-auth is not set.

Consequently, we need to set it upon OvirtProxy creation in order not to
break this usecase. We don't add the header in RestProxyCall as was done
before as we want to be able to disable this addition after
OvirtProxy::sso-token has been set.
---
govirt/ovirt-proxy.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/govirt/ovirt-proxy.c b/govirt/ovirt-proxy.c
index fc0273f..08e42d2 100644
--- a/govirt/ovirt-proxy.c
+++ b/govirt/ovirt-proxy.c
@@ -801,9 +801,6 @@ static void ovirt_proxy_set_session_id(OvirtProxy *proxy, const char *session_id
cookie = soup_cookie_new("JSESSIONID", session_id, domain, "/ovirt-engine/api", -1);
soup_cookie_jar_add_cookie(proxy->priv->cookie_jar, cookie);
proxy->priv->jsessionid_cookie = cookie;
- ovirt_proxy_add_header(proxy, "Prefer", "persistent-auth");
- } else {
- ovirt_proxy_add_header(proxy, "Prefer", NULL);
}
g_free(url);
}
@@ -815,6 +812,7 @@ static void ovirt_proxy_set_sso_token(OvirtProxy *proxy, const char *sso_token)
g_free(proxy->priv->sso_token);
proxy->priv->sso_token = g_strdup(sso_token);

+ ovirt_proxy_add_header(proxy, "Prefer", NULL);
header_value = g_strdup_printf("Bearer %s", sso_token);
ovirt_proxy_add_header(proxy, "Authorization", header_value);
g_free(header_value);
@@ -903,6 +901,7 @@ static void ovirt_proxy_constructed(GObject *gobject)
g_warning("Disabling strict checking of SSL certificates");
g_object_set(OVIRT_PROXY(gobject), "ssl-strict", FALSE, NULL);
}
+ ovirt_proxy_add_header(OVIRT_PROXY(gobject), "Prefer", "persistent-auth");

/* Chain up to the parent class */
if (G_OBJECT_CLASS(ovirt_proxy_parent_class)->constructed)

28
SOURCES/0002-Force-use-of-v3-REST-API.patch

@ -0,0 +1,28 @@ @@ -0,0 +1,28 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Christophe Fergeau <cfergeau@redhat.com>
Date: Thu, 16 Jun 2016 11:10:27 +0200
Subject: [PATCH] Force use of v3 REST API

oVirt 4.0 introduced a slightly incompatible REST API, see
https://github.com/oVirt/ovirt-engine/tree/master/backend/manager/modules/restapi
A short term fix is to send a "Version: 3" header with each request,
which this commit does. This might stop working with oVirt 4.1 though.

Longer term fix is tracked in
https://bugzilla.gnome.org/show_bug.cgi?id=767724
---
govirt/ovirt-proxy.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/govirt/ovirt-proxy.c b/govirt/ovirt-proxy.c
index 08e42d2..efe3284 100644
--- a/govirt/ovirt-proxy.c
+++ b/govirt/ovirt-proxy.c
@@ -902,6 +902,7 @@ static void ovirt_proxy_constructed(GObject *gobject)
g_object_set(OVIRT_PROXY(gobject), "ssl-strict", FALSE, NULL);
}
ovirt_proxy_add_header(OVIRT_PROXY(gobject), "Prefer", "persistent-auth");
+ ovirt_proxy_add_header(OVIRT_PROXY(gobject), "Version", "3");

/* Chain up to the parent class */
if (G_OBJECT_CLASS(ovirt_proxy_parent_class)->constructed)

22
SOURCES/0003-New-storage-format-added-in-oVirt-4.1.patch

@ -0,0 +1,22 @@ @@ -0,0 +1,22 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: "Eduardo Lima (Etrunko)" <etrunko@redhat.com>
Date: Tue, 21 Feb 2017 11:20:38 -0300
Subject: [PATCH] New storage format added in oVirt 4.1

Signed-off-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
---
govirt/ovirt-storage-domain.h | 1 +
1 file changed, 1 insertion(+)

diff --git a/govirt/ovirt-storage-domain.h b/govirt/ovirt-storage-domain.h
index 15c3340..79f1741 100644
--- a/govirt/ovirt-storage-domain.h
+++ b/govirt/ovirt-storage-domain.h
@@ -41,6 +41,7 @@ typedef enum {
OVIRT_STORAGE_DOMAIN_FORMAT_VERSION_V1,
OVIRT_STORAGE_DOMAIN_FORMAT_VERSION_V2,
OVIRT_STORAGE_DOMAIN_FORMAT_VERSION_V3,
+ OVIRT_STORAGE_DOMAIN_FORMAT_VERSION_V4,
} OvirtStorageDomainFormatVersion;

typedef enum {

35
SOURCES/0004-proxy-Hold-reference-to-cancellable-object.patch

@ -0,0 +1,35 @@ @@ -0,0 +1,35 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: "Eduardo Lima (Etrunko)" <etrunko@redhat.com>
Date: Thu, 2 Feb 2017 15:11:42 -0200
Subject: [PATCH] proxy: Hold reference to cancellable object

Being an asynchronous operation, there is no guarantee that the object
is valid by the time of the cleanup, so we hold a reference to it to
ensure it.

Signed-off-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
---
govirt/ovirt-proxy.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/govirt/ovirt-proxy.c b/govirt/ovirt-proxy.c
index efe3284..2b690b6 100644
--- a/govirt/ovirt-proxy.c
+++ b/govirt/ovirt-proxy.c
@@ -220,6 +220,7 @@ static void ovirt_proxy_call_async_data_free(OvirtProxyCallAsyncData *data)
if ((data->cancellable != NULL) && (data->cancellable_cb_id != 0)) {
g_cancellable_disconnect(data->cancellable, data->cancellable_cb_id);
}
+ g_clear_object(&data->cancellable);
g_slice_free(OvirtProxyCallAsyncData, data);
}

@@ -284,7 +285,7 @@ void ovirt_rest_call_async(OvirtRestCall *call,
data->call_user_data = user_data;
data->destroy_call_data = destroy_func;
if (cancellable != NULL) {
- data->cancellable = cancellable;
+ data->cancellable = g_object_ref(cancellable);
data->cancellable_cb_id = g_cancellable_connect(cancellable,
G_CALLBACK (call_async_cancelled_cb),
call, NULL);

40
SOURCES/0005-proxy-Check-if-operation-is-cancelled-before-disconn.patch

@ -0,0 +1,40 @@ @@ -0,0 +1,40 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: "Eduardo Lima (Etrunko)" <etrunko@redhat.com>
Date: Thu, 2 Feb 2017 15:13:48 -0200
Subject: [PATCH] proxy: Check if operation is cancelled before disconnecting
signal

According to the documentation, g_cancellable_disconnect() waits for the
signal handler to finish, and if it is called from the handler itself, it
will result in a deadlock. To avoid it, we check if the operation is
cancelled and if so, call g_signal_handler_disconnect() instead of
g_cancellable_disconnect().

https://developer.gnome.org/gio/stable/GCancellable.html#g-cancellable-disconnect

Signed-off-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
---
govirt/ovirt-proxy.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/govirt/ovirt-proxy.c b/govirt/ovirt-proxy.c
index 2b690b6..921e22e 100644
--- a/govirt/ovirt-proxy.c
+++ b/govirt/ovirt-proxy.c
@@ -218,7 +218,15 @@ static void ovirt_proxy_call_async_data_free(OvirtProxyCallAsyncData *data)
g_object_unref(G_OBJECT(data->result));
}
if ((data->cancellable != NULL) && (data->cancellable_cb_id != 0)) {
- g_cancellable_disconnect(data->cancellable, data->cancellable_cb_id);
+ if (g_cancellable_is_cancelled(data->cancellable)) {
+ /* Cancellable has already been cancelled, we don't need to use
+ * g_cancellable_disconnect() to disconnect the signal handler
+ * as we know the 'cancelled' signal is no longer going to be emitted
+ */
+ g_signal_handler_disconnect(data->cancellable, data->cancellable_cb_id);
+ } else {
+ g_cancellable_disconnect(data->cancellable, data->cancellable_cb_id);
+ }
}
g_clear_object(&data->cancellable);
g_slice_free(OvirtProxyCallAsyncData, data);

107
SOURCES/0006-storage-domain-Factor-out-property-value-setting-fro.patch

@ -0,0 +1,107 @@ @@ -0,0 +1,107 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: "Eduardo Lima (Etrunko)" <etrunko@redhat.com>
Date: Wed, 10 May 2017 15:45:36 -0300
Subject: [PATCH] storage-domain: Factor out property value setting from
ovirt_resource_parse_xml()

Instead of using chained if/else blocks, use a switch for the type. With
this small refactor we prepare to move this function to ovirt-utils so
that it can be reused by other objects.

Signed-off-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
---
govirt/ovirt-storage-domain.c | 74 ++++++++++++++++++++++-------------
1 file changed, 47 insertions(+), 27 deletions(-)

diff --git a/govirt/ovirt-storage-domain.c b/govirt/ovirt-storage-domain.c
index e7308bb..4087d75 100644
--- a/govirt/ovirt-storage-domain.c
+++ b/govirt/ovirt-storage-domain.c
@@ -277,6 +277,51 @@ OvirtStorageDomain *ovirt_storage_domain_new(void)
return OVIRT_STORAGE_DOMAIN(domain);
}

+static gboolean
+_set_property_value_from_type(GValue *value,
+ GType type,
+ const char *value_str,
+ RestXmlNode *node)
+{
+ gboolean ret = TRUE;
+
+ if (g_type_is_a(type, OVIRT_TYPE_RESOURCE)) {
+ GObject *resource_value = g_initable_new(type, NULL, NULL, "xml-node", node, NULL);
+ g_value_set_object(value, resource_value);
+ goto end;
+ }
+
+ /* All other types require valid value_str */
+ if (value_str == NULL)
+ return FALSE;
+
+ if (G_TYPE_IS_ENUM(type)) {
+ int enum_value = ovirt_utils_genum_get_value(type, value_str, 0);
+ g_value_set_enum(value, enum_value);
+ goto end;
+ }
+
+ switch(type) {
+ case G_TYPE_BOOLEAN: {
+ gboolean bool_value = ovirt_utils_boolean_from_string(value_str);
+ g_value_set_boolean(value, bool_value);
+ break;
+ }
+ case G_TYPE_UINT64: {
+ guint64 int64_value = g_ascii_strtoull(value_str, NULL, 0);
+ g_value_set_uint64(value, int64_value);
+ break;
+ }
+ default: {
+ g_warning("Unexpected type '%s' with value '%s'", g_type_name(type), value_str);
+ ret = FALSE;
+ }
+ }
+
+end:
+ return ret;
+}
+
typedef struct {
const char *xml_node;
GType type;
@@ -296,34 +341,9 @@ ovirt_resource_parse_xml(OvirtResource *resource,
GValue value = { 0, };

value_str = ovirt_rest_xml_node_get_content_from_path(node, elements->xml_node);
- if (value_str == NULL) {
- continue;
- }
g_value_init(&value, elements->type);
-
- if (G_TYPE_IS_ENUM(elements->type)) {
- int enum_value;
- enum_value = ovirt_utils_genum_get_value(elements->type,
- value_str, 0);
- g_value_set_enum(&value, enum_value);
- } else if (elements->type == G_TYPE_BOOLEAN) {
- gboolean bool_value;
-
- bool_value = ovirt_utils_boolean_from_string(value_str);
- g_value_set_boolean(&value, bool_value);
- } else if (elements->type == G_TYPE_UINT64) {
- guint64 int64_value;
-
- int64_value = g_ascii_strtoull(value_str, NULL, 0);
- g_value_set_uint64(&value, int64_value);
- } else if (g_type_is_a(elements->type, OVIRT_TYPE_RESOURCE)) {
- GObject *resource_value;
-
- resource_value = g_initable_new(elements->type, NULL, NULL,
- "xml-node", node, NULL);
- g_value_set_object(&value, resource_value);
- }
- g_object_set_property(G_OBJECT(resource), elements->prop_name, &value);
+ if (_set_property_value_from_type(&value, elements->type, value_str, node))
+ g_object_set_property(G_OBJECT(resource), elements->prop_name, &value);
g_value_unset(&value);
}

89
SOURCES/0007-storage-domain-use-explicit-initialization-of-struct.patch

@ -0,0 +1,89 @@ @@ -0,0 +1,89 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: "Eduardo Lima (Etrunko)" <etrunko@redhat.com>
Date: Wed, 10 May 2017 16:12:01 -0300
Subject: [PATCH] storage-domain: use explicit initialization of struct
OvirtXmlElement members

Also, members have been reordered and the xml_node field has been
renamed to more proper xml_path.

Signed-off-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
---
govirt/ovirt-storage-domain.c | 46 ++++++++++++++++++++++++++---------
1 file changed, 34 insertions(+), 12 deletions(-)

diff --git a/govirt/ovirt-storage-domain.c b/govirt/ovirt-storage-domain.c
index 4087d75..07c0ef0 100644
--- a/govirt/ovirt-storage-domain.c
+++ b/govirt/ovirt-storage-domain.c
@@ -323,9 +323,9 @@ end:
}

typedef struct {
- const char *xml_node;
- GType type;
const char *prop_name;
+ GType type;
+ const char *xml_path;
} OvirtXmlElement;

static gboolean
@@ -336,11 +336,12 @@ ovirt_resource_parse_xml(OvirtResource *resource,
g_return_val_if_fail(OVIRT_IS_RESOURCE(resource), FALSE);
g_return_val_if_fail(elements != NULL, FALSE);

- for (;elements->xml_node != NULL; elements++) {
+ for (;elements->xml_path != NULL; elements++) {
const char *value_str;
GValue value = { 0, };

- value_str = ovirt_rest_xml_node_get_content_from_path(node, elements->xml_node);
+ value_str = ovirt_rest_xml_node_get_content_from_path(node, elements->xml_path);
+
g_value_init(&value, elements->type);
if (_set_property_value_from_type(&value, elements->type, value_str, node))
g_object_set_property(G_OBJECT(resource), elements->prop_name, &value);
@@ -355,14 +356,35 @@ ovirt_storage_domain_refresh_from_xml(OvirtStorageDomain *domain,
RestXmlNode *node)
{
OvirtXmlElement storage_domain_elements[] = {
- { "type", OVIRT_TYPE_STORAGE_DOMAIN_TYPE, "type" },
- { "master", G_TYPE_BOOLEAN, "master" },
- { "available", G_TYPE_UINT64, "available" },
- { "used", G_TYPE_UINT64, "used" },
- { "committed", G_TYPE_UINT64, "committed" },
- { "storage_format", OVIRT_TYPE_STORAGE_DOMAIN_FORMAT_VERSION, "version" },
- { "status/state", OVIRT_TYPE_STORAGE_DOMAIN_STATE, "state" },
- { NULL, G_TYPE_INVALID, NULL }
+ { .prop_name = "type",
+ .type = OVIRT_TYPE_STORAGE_DOMAIN_TYPE,
+ .xml_path = "type",
+ },
+ { .prop_name = "master",
+ .type = G_TYPE_BOOLEAN,
+ .xml_path = "master",
+ },
+ { .prop_name = "available",
+ .type = G_TYPE_UINT64,
+ .xml_path = "available",
+ },
+ { .prop_name = "used",
+ .type = G_TYPE_UINT64,
+ .xml_path = "used",
+ },
+ { .prop_name = "committed",
+ .type = G_TYPE_UINT64,
+ .xml_path = "committed",
+ },
+ { .prop_name = "version",
+ .type = OVIRT_TYPE_STORAGE_DOMAIN_FORMAT_VERSION,
+ .xml_path = "storage_format",
+ },
+ { .prop_name = "state",
+ .type = OVIRT_TYPE_STORAGE_DOMAIN_STATE,
+ .xml_path = "status/state",
+ },
+ { NULL , }
};

return ovirt_resource_parse_xml(OVIRT_RESOURCE(domain), node, storage_domain_elements);

325
SOURCES/0008-storage-domain-Move-out-ovirt_resource_parse_xml-to-.patch

@ -0,0 +1,325 @@ @@ -0,0 +1,325 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: "Eduardo Lima (Etrunko)" <etrunko@redhat.com>
Date: Thu, 22 Jun 2017 13:06:53 -0300
Subject: [PATCH] storage-domain: Move out ovirt_resource_parse_xml() to
ovirt-utils

There were a couple of tweaks to the function:

1) Renamed to ovirt_rest_xml_node_parse()
More suited to the task performed.

2) Validates GObject instead of OvirtResource
This removes the restriction of usage by a OvirtResource, and in the
future it can also be used by OvirtVmDisplay to parse the elements.
It also makes it more coherent to its purpose, as the function only
sets properties of a GObject and does not really require a
OvirtResource.

Signed-off-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
---
govirt/ovirt-storage-domain.c | 152 +++++++---------------------------
govirt/ovirt-utils.c | 71 +++++++++++++++-
govirt/ovirt-utils.h | 13 ++-
3 files changed, 113 insertions(+), 123 deletions(-)

diff --git a/govirt/ovirt-storage-domain.c b/govirt/ovirt-storage-domain.c
index 07c0ef0..0582203 100644
--- a/govirt/ovirt-storage-domain.c
+++ b/govirt/ovirt-storage-domain.c
@@ -53,10 +53,6 @@ enum {
PROP_STATE
};

-static gboolean
-ovirt_storage_domain_refresh_from_xml(OvirtStorageDomain *domain,
- RestXmlNode *node);
-
static void ovirt_storage_domain_get_property(GObject *object,
guint prop_id,
GValue *value,
@@ -145,10 +141,39 @@ static gboolean ovirt_storage_domain_init_from_xml(OvirtResource *resource,
{
gboolean parsed_ok;
OvirtResourceClass *parent_class;
- OvirtStorageDomain *domain;
+ OvirtXmlElement storage_domain_elements[] = {
+ { .prop_name = "type",
+ .type = OVIRT_TYPE_STORAGE_DOMAIN_TYPE,
+ .xml_path = "type",
+ },
+ { .prop_name = "master",
+ .type = G_TYPE_BOOLEAN,
+ .xml_path = "master",
+ },
+ { .prop_name = "available",
+ .type = G_TYPE_UINT64,
+ .xml_path = "available",
+ },
+ { .prop_name = "used",
+ .type = G_TYPE_UINT64,
+ .xml_path = "used",
+ },
+ { .prop_name = "committed",
+ .type = G_TYPE_UINT64,
+ .xml_path = "committed",
+ },
+ { .prop_name = "version",
+ .type = OVIRT_TYPE_STORAGE_DOMAIN_FORMAT_VERSION,
+ .xml_path = "storage_format",
+ },
+ { .prop_name = "state",
+ .type = OVIRT_TYPE_STORAGE_DOMAIN_STATE,
+ .xml_path = "status/state",
+ },
+ { NULL , }
+ };

- domain = OVIRT_STORAGE_DOMAIN(resource);
- parsed_ok = ovirt_storage_domain_refresh_from_xml(domain, node);
+ parsed_ok = ovirt_rest_xml_node_parse(node, G_OBJECT(resource), storage_domain_elements);
if (!parsed_ok) {
return FALSE;
}
@@ -277,119 +302,6 @@ OvirtStorageDomain *ovirt_storage_domain_new(void)
return OVIRT_STORAGE_DOMAIN(domain);
}

-static gboolean
-_set_property_value_from_type(GValue *value,
- GType type,
- const char *value_str,
- RestXmlNode *node)
-{
- gboolean ret = TRUE;
-
- if (g_type_is_a(type, OVIRT_TYPE_RESOURCE)) {
- GObject *resource_value = g_initable_new(type, NULL, NULL, "xml-node", node, NULL);
- g_value_set_object(value, resource_value);
- goto end;
- }
-
- /* All other types require valid value_str */
- if (value_str == NULL)
- return FALSE;
-
- if (G_TYPE_IS_ENUM(type)) {
- int enum_value = ovirt_utils_genum_get_value(type, value_str, 0);
- g_value_set_enum(value, enum_value);
- goto end;
- }
-
- switch(type) {
- case G_TYPE_BOOLEAN: {
- gboolean bool_value = ovirt_utils_boolean_from_string(value_str);
- g_value_set_boolean(value, bool_value);
- break;
- }
- case G_TYPE_UINT64: {
- guint64 int64_value = g_ascii_strtoull(value_str, NULL, 0);
- g_value_set_uint64(value, int64_value);
- break;
- }
- default: {
- g_warning("Unexpected type '%s' with value '%s'", g_type_name(type), value_str);
- ret = FALSE;
- }
- }
-
-end:
- return ret;
-}
-
-typedef struct {
- const char *prop_name;
- GType type;
- const char *xml_path;
-} OvirtXmlElement;
-
-static gboolean
-ovirt_resource_parse_xml(OvirtResource *resource,
- RestXmlNode *node,
- OvirtXmlElement *elements)
-{
- g_return_val_if_fail(OVIRT_IS_RESOURCE(resource), FALSE);
- g_return_val_if_fail(elements != NULL, FALSE);
-
- for (;elements->xml_path != NULL; elements++) {
- const char *value_str;
- GValue value = { 0, };
-
- value_str = ovirt_rest_xml_node_get_content_from_path(node, elements->xml_path);
-
- g_value_init(&value, elements->type);
- if (_set_property_value_from_type(&value, elements->type, value_str, node))
- g_object_set_property(G_OBJECT(resource), elements->prop_name, &value);
- g_value_unset(&value);
- }
-
- return TRUE;
-}
-
-static gboolean
-ovirt_storage_domain_refresh_from_xml(OvirtStorageDomain *domain,
- RestXmlNode *node)
-{
- OvirtXmlElement storage_domain_elements[] = {
- { .prop_name = "type",
- .type = OVIRT_TYPE_STORAGE_DOMAIN_TYPE,
- .xml_path = "type",
- },
- { .prop_name = "master",
- .type = G_TYPE_BOOLEAN,
- .xml_path = "master",
- },
- { .prop_name = "available",
- .type = G_TYPE_UINT64,
- .xml_path = "available",
- },
- { .prop_name = "used",
- .type = G_TYPE_UINT64,
- .xml_path = "used",
- },
- { .prop_name = "committed",
- .type = G_TYPE_UINT64,
- .xml_path = "committed",
- },
- { .prop_name = "version",
- .type = OVIRT_TYPE_STORAGE_DOMAIN_FORMAT_VERSION,
- .xml_path = "storage_format",
- },
- { .prop_name = "state",
- .type = OVIRT_TYPE_STORAGE_DOMAIN_STATE,
- .xml_path = "status/state",
- },
- { NULL , }
- };
-
- return ovirt_resource_parse_xml(OVIRT_RESOURCE(domain), node, storage_domain_elements);
-}
-

/**
* ovirt_storage_domain_get_files:
diff --git a/govirt/ovirt-utils.c b/govirt/ovirt-utils.c
index 0e0134c..44ea7da 100644
--- a/govirt/ovirt-utils.c
+++ b/govirt/ovirt-utils.c
@@ -31,6 +31,7 @@
#include "ovirt-utils.h"

#include "ovirt-error.h"
+#include "ovirt-resource.h"

RestXmlNode *
ovirt_rest_xml_node_from_call(RestProxyCall *call)
@@ -77,7 +78,7 @@ ovirt_rest_xml_node_get_content_va(RestXmlNode *node,
return node->content;
}

-G_GNUC_INTERNAL const char *
+static const char *
ovirt_rest_xml_node_get_content_from_path(RestXmlNode *node, const char *path)
{
GStrv pathv;
@@ -109,6 +110,74 @@ ovirt_rest_xml_node_get_content(RestXmlNode *node, ...)
return content;
}

+static gboolean
+_set_property_value_from_type(GValue *value,
+ GType type,
+ const char *value_str,
+ RestXmlNode *node)
+{
+ gboolean ret = TRUE;
+
+ if (g_type_is_a(type, OVIRT_TYPE_RESOURCE)) {
+ GObject *resource_value = g_initable_new(type, NULL, NULL, "xml-node", node, NULL);
+ g_value_set_object(value, resource_value);
+ goto end;
+ }
+
+ /* All other types require valid value_str */
+ if (value_str == NULL)
+ return FALSE;
+
+ if (G_TYPE_IS_ENUM(type)) {
+ int enum_value = ovirt_utils_genum_get_value(type, value_str, 0);
+ g_value_set_enum(value, enum_value);
+ goto end;
+ }
+
+ switch(type) {
+ case G_TYPE_BOOLEAN: {
+ gboolean bool_value = ovirt_utils_boolean_from_string(value_str);
+ g_value_set_boolean(value, bool_value);
+ break;
+ }
+ case G_TYPE_UINT64: {
+ guint64 int64_value = g_ascii_strtoull(value_str, NULL, 0);
+ g_value_set_uint64(value, int64_value);
+ break;
+ }
+ default: {
+ g_warning("Unexpected type '%s' with value '%s'", g_type_name(type), value_str);
+ ret = FALSE;
+ }
+ }
+
+end:
+ return ret;
+}
+
+gboolean
+ovirt_rest_xml_node_parse(RestXmlNode *node,
+ GObject *object,
+ OvirtXmlElement *elements)
+{
+ g_return_val_if_fail(G_IS_OBJECT(object), FALSE);
+ g_return_val_if_fail(elements != NULL, FALSE);
+
+ for (;elements->xml_path != NULL; elements++) {
+ const char *value_str;
+ GValue value = { 0, };
+
+ value_str = ovirt_rest_xml_node_get_content_from_path(node, elements->xml_path);
+
+ g_value_init(&value, elements->type);
+ if (_set_property_value_from_type(&value, elements->type, value_str, node))
+ g_object_set_property(object, elements->prop_name, &value);
+ g_value_unset(&value);
+ }
+
+ return TRUE;
+}
+

/* These 2 functions come from
* libvirt-glib/libvirt-gconfig/libvirt-gconfig-helpers.c
diff --git a/govirt/ovirt-utils.h b/govirt/ovirt-utils.h
index 3f43fc9..4fd4164 100644
--- a/govirt/ovirt-utils.h
+++ b/govirt/ovirt-utils.h
@@ -27,10 +27,19 @@

G_BEGIN_DECLS

+typedef struct _OvirtXmlElement OvirtXmlElement;
+struct _OvirtXmlElement
+{
+ const char *prop_name;
+ GType type;
+ const char *xml_path;
+};
+
RestXmlNode *ovirt_rest_xml_node_from_call(RestProxyCall *call);
const char *ovirt_rest_xml_node_get_content(RestXmlNode *node, ...);
-const char *ovirt_rest_xml_node_get_content_from_path(RestXmlNode *node,
- const char *path);
+gboolean ovirt_rest_xml_node_parse(RestXmlNode *node,
+ GObject *object,
+ OvirtXmlElement *elements);
gboolean ovirt_utils_gerror_from_xml_fault(RestXmlNode *root, GError **error);
gboolean g_object_set_guint_property_from_xml(GObject *g_object,
RestXmlNode *node,

57
SOURCES/0009-utils-Remove-unused-function-ovirt_rest_xml_node_get.patch

@ -0,0 +1,57 @@ @@ -0,0 +1,57 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: "Eduardo Lima (Etrunko)" <etrunko@redhat.com>
Date: Fri, 28 Apr 2017 17:16:31 -0300
Subject: [PATCH] utils: Remove unused function
ovirt_rest_xml_node_get_content()

Most uses were removed in dbf8dd85 "Add generic resource parser" and the
last use in 18d7c005 "storage-domain: Parse storage domain status"

Signed-off-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
---
govirt/ovirt-utils.c | 19 -------------------
govirt/ovirt-utils.h | 1 -
2 files changed, 20 deletions(-)

diff --git a/govirt/ovirt-utils.c b/govirt/ovirt-utils.c
index 44ea7da..951c693 100644
--- a/govirt/ovirt-utils.c
+++ b/govirt/ovirt-utils.c
@@ -91,25 +91,6 @@ ovirt_rest_xml_node_get_content_from_path(RestXmlNode *node, const char *path)
return content;
}

-G_GNUC_INTERNAL const char *
-ovirt_rest_xml_node_get_content(RestXmlNode *node, ...)
-{
- va_list args;
- const char *content;
-
- g_return_val_if_fail(node != NULL, NULL);
-
- va_start(args, node);
-
- content = ovirt_rest_xml_node_get_content_va(node, &args, NULL);
-
- va_end(args);
-
- g_warn_if_fail(node != NULL);
-
- return content;
-}
-
static gboolean
_set_property_value_from_type(GValue *value,
GType type,
diff --git a/govirt/ovirt-utils.h b/govirt/ovirt-utils.h
index 4fd4164..e786311 100644
--- a/govirt/ovirt-utils.h
+++ b/govirt/ovirt-utils.h
@@ -36,7 +36,6 @@ struct _OvirtXmlElement
};

RestXmlNode *ovirt_rest_xml_node_from_call(RestProxyCall *call);
-const char *ovirt_rest_xml_node_get_content(RestXmlNode *node, ...);
gboolean ovirt_rest_xml_node_parse(RestXmlNode *node,
GObject *object,
OvirtXmlElement *elements);

91
SOURCES/0010-utils-Rename-ovirt_rest_xml_node_get_content_va-to-o.patch

@ -0,0 +1,91 @@ @@ -0,0 +1,91 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: "Eduardo Lima (Etrunko)" <etrunko@redhat.com>
Date: Fri, 19 May 2017 00:31:46 -0300
Subject: [PATCH] utils: Rename ovirt_rest_xml_node_get_content_va() to
ovirt_rest_xml_node_find()

It is more useful to make this function retrieve a sub node and let the
caller do what it wants with that node, instead of returning the content
directly.

Signed-off-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
---
govirt/ovirt-utils.c | 59 +++++++++++++++++++-------------------------
1 file changed, 26 insertions(+), 33 deletions(-)

diff --git a/govirt/ovirt-utils.c b/govirt/ovirt-utils.c
index 951c693..c0541e9 100644
--- a/govirt/ovirt-utils.c
+++ b/govirt/ovirt-utils.c
@@ -50,45 +50,38 @@ ovirt_rest_xml_node_from_call(RestProxyCall *call)
return node;
}

-static const char *
-ovirt_rest_xml_node_get_content_va(RestXmlNode *node,
- va_list *args,
- GStrv str_array)
-{
- g_return_val_if_fail((args != NULL) || (str_array != NULL), NULL);
-
- while (TRUE) {
- const char *node_name;
-
- if (args != NULL) {
- node_name = va_arg(*args, const char *);
- } else {
- node_name = *str_array;
- str_array++;
- }
- if (node_name == NULL)
- break;
- node = rest_xml_node_find(node, node_name);
- if (node == NULL) {
- g_debug("could not find XML node '%s'", node_name);
- return NULL;
- }
- }
-
- return node->content;
-}
-
-static const char *
-ovirt_rest_xml_node_get_content_from_path(RestXmlNode *node, const char *path)
+static RestXmlNode *
+ovirt_rest_xml_node_find(RestXmlNode *node, const char *path)
{
+ guint i;
GStrv pathv;
- const char *content;
+
+ g_return_val_if_fail((path != NULL), NULL);

pathv = g_strsplit(path, "/", -1);
- content = ovirt_rest_xml_node_get_content_va(node, NULL, pathv);
+
+ for (i = 0; i < g_strv_length(pathv); ++i) {
+ node = rest_xml_node_find(node, pathv[i]);
+ if (node == NULL) {
+ g_debug("could not find XML node '%s'", pathv[i]);
+ break;
+ }
+ }
+
g_strfreev(pathv);

- return content;
+ return node;
+}
+
+static const char *
+ovirt_rest_xml_node_get_content_from_path(RestXmlNode *node, const char *path)
+{
+ node = ovirt_rest_xml_node_find(node, path);
+
+ if (node == NULL)
+ return NULL;
+
+ return node->content;
}

static gboolean

65
SOURCES/0011-utils-Retrieve-node-attributes-in-ovirt_resource_par.patch

@ -0,0 +1,65 @@ @@ -0,0 +1,65 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: "Eduardo Lima (Etrunko)" <etrunko@redhat.com>
Date: Thu, 18 May 2017 17:53:33 -0300
Subject: [PATCH] utils: Retrieve node attributes in ovirt_resource_parse_xml()

This commit adds a new field to the OvirtXmlElement struct, which is
used to retrieve an attribute from the xml node. It is optional, meaning
that, if not informed, the function will still retrieve the node
contents instead.

We also introduce ovirt_rest_xml_node_get_attr_from_path() function,
to retrieve the given attribute value from the path below the node, much
similar to ovirt_rest_xml_node_get_content_from_path().

Signed-off-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
---
govirt/ovirt-utils.c | 15 ++++++++++++++-
govirt/ovirt-utils.h | 1 +
2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/govirt/ovirt-utils.c b/govirt/ovirt-utils.c
index c0541e9..b9b7c15 100644
--- a/govirt/ovirt-utils.c
+++ b/govirt/ovirt-utils.c
@@ -84,6 +84,16 @@ ovirt_rest_xml_node_get_content_from_path(RestXmlNode *node, const char *path)
return node->content;
}

+static const char *
+ovirt_rest_xml_node_get_attr_from_path(RestXmlNode *node, const char *path, const char *attr)
+{
+ node = ovirt_rest_xml_node_find(node, path);
+ if (node == NULL)
+ return NULL;
+
+ return rest_xml_node_get_attr(node, attr);
+}
+
static gboolean
_set_property_value_from_type(GValue *value,
GType type,
@@ -141,7 +151,10 @@ ovirt_rest_xml_node_parse(RestXmlNode *node,
const char *value_str;
GValue value = { 0, };

- value_str = ovirt_rest_xml_node_get_content_from_path(node, elements->xml_path);
+ if (elements->xml_attr != NULL)
+ value_str = ovirt_rest_xml_node_get_attr_from_path(node, elements->xml_path, elements->xml_attr);
+ else
+ value_str = ovirt_rest_xml_node_get_content_from_path(node, elements->xml_path);

g_value_init(&value, elements->type);
if (_set_property_value_from_type(&value, elements->type, value_str, node))
diff --git a/govirt/ovirt-utils.h b/govirt/ovirt-utils.h
index e786311..545847a 100644
--- a/govirt/ovirt-utils.h
+++ b/govirt/ovirt-utils.h
@@ -33,6 +33,7 @@ struct _OvirtXmlElement
const char *prop_name;
GType type;
const char *xml_path;
+ const char *xml_attr; /* if NULL, retrieve node content instead of attribute */
};

RestXmlNode *ovirt_rest_xml_node_from_call(RestProxyCall *call);

26
SOURCES/0012-utils-Support-G_TYPE_STRING-in-_set_property_value_f.patch

@ -0,0 +1,26 @@ @@ -0,0 +1,26 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: "Eduardo Lima (Etrunko)" <etrunko@redhat.com>
Date: Wed, 10 May 2017 15:46:27 -0300
Subject: [PATCH] utils: Support G_TYPE_STRING in
_set_property_value_from_type()

Signed-off-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
---
govirt/ovirt-utils.c | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/govirt/ovirt-utils.c b/govirt/ovirt-utils.c
index b9b7c15..fafb9ec 100644
--- a/govirt/ovirt-utils.c
+++ b/govirt/ovirt-utils.c
@@ -124,6 +124,10 @@ _set_property_value_from_type(GValue *value,
g_value_set_boolean(value, bool_value);
break;
}
+ case G_TYPE_STRING: {
+ g_value_set_string(value, value_str);
+ break;
+ }
case G_TYPE_UINT64: {
guint64 int64_value = g_ascii_strtoull(value_str, NULL, 0);
g_value_set_uint64(value, int64_value);

111
SOURCES/0013-utils-Support-G_TYPE_STRV-in-_set_property_value_fro.patch

@ -0,0 +1,111 @@ @@ -0,0 +1,111 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: "Eduardo Lima (Etrunko)" <etrunko@redhat.com>
Date: Thu, 11 May 2017 17:31:43 -0300
Subject: [PATCH] utils: Support G_TYPE_STRV in _set_property_value_from_type()

Because user can require either the attribute or the node content, it
was necessary to change the function signature to receive both
parameters.

Signed-off-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
---
govirt/ovirt-utils.c | 63 ++++++++++++++++++++++++++++++++++++++------
1 file changed, 55 insertions(+), 8 deletions(-)

diff --git a/govirt/ovirt-utils.c b/govirt/ovirt-utils.c
index fafb9ec..a200e48 100644
--- a/govirt/ovirt-utils.c
+++ b/govirt/ovirt-utils.c
@@ -94,20 +94,73 @@ ovirt_rest_xml_node_get_attr_from_path(RestXmlNode *node, const char *path, cons
return rest_xml_node_get_attr(node, attr);
}

+static GStrv
+ovirt_rest_xml_node_get_str_array_from_path(RestXmlNode *node, const char *path, const char *attr)
+{
+ GArray *array;
+ GHashTableIter iter;
+ gpointer sub_node;
+
+ node = ovirt_rest_xml_node_find(node, path);
+ if (node == NULL)
+ return NULL;
+
+ array = g_array_new(TRUE, FALSE, sizeof(gchar *));
+
+ g_hash_table_iter_init(&iter, node->children);
+ while (g_hash_table_iter_next(&iter, NULL, &sub_node)) {
+ const char *value;
+ char *array_value;
+
+ node = (RestXmlNode *) sub_node;
+
+ if (attr != NULL)
+ value = rest_xml_node_get_attr(node, attr);
+ else
+ value = node->content;
+
+ if (value == NULL) {
+ g_warning("node %s%s is NULL", attr ? "attribute:" : "content", attr ? attr : "" );
+ continue;
+ }
+
+ array_value = g_strdup(value);
+ g_array_append_val(array, array_value);
+ }
+
+ return (GStrv) g_array_free(array, FALSE);
+}
+
static gboolean
_set_property_value_from_type(GValue *value,
GType type,
- const char *value_str,
+ const char *path,
+ const char *attr,
RestXmlNode *node)
{
gboolean ret = TRUE;
+ const char *value_str;

if (g_type_is_a(type, OVIRT_TYPE_RESOURCE)) {
GObject *resource_value = g_initable_new(type, NULL, NULL, "xml-node", node, NULL);
g_value_set_object(value, resource_value);
goto end;
+ } else if (g_type_is_a(type, G_TYPE_STRV)) {
+ GStrv strv_value = ovirt_rest_xml_node_get_str_array_from_path(node, path, attr);
+ if (strv_value == NULL) {
+ ret = FALSE;
+ goto end;
+ }
+
+ g_value_take_boxed(value, strv_value);
+ goto end;
}

+ if (attr != NULL)
+ value_str = ovirt_rest_xml_node_get_attr_from_path(node, path, attr);
+ else
+ value_str = ovirt_rest_xml_node_get_content_from_path(node, path);
+
/* All other types require valid value_str */
if (value_str == NULL)
return FALSE;
@@ -152,16 +205,10 @@ ovirt_rest_xml_node_parse(RestXmlNode *node,
g_return_val_if_fail(elements != NULL, FALSE);

for (;elements->xml_path != NULL; elements++) {
- const char *value_str;
GValue value = { 0, };

- if (elements->xml_attr != NULL)
- value_str = ovirt_rest_xml_node_get_attr_from_path(node, elements->xml_path, elements->xml_attr);
- else
- value_str = ovirt_rest_xml_node_get_content_from_path(node, elements->xml_path);
-
g_value_init(&value, elements->type);
- if (_set_property_value_from_type(&value, elements->type, value_str, node))
+ if (_set_property_value_from_type(&value, elements->type, elements->xml_path, elements->xml_attr, node))
g_object_set_property(object, elements->prop_name, &value);
g_value_unset(&value);
}

203
SOURCES/0014-Introduce-auxiliary-function-ovirt_sub_collection_ne.patch

@ -0,0 +1,203 @@ @@ -0,0 +1,203 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: "Eduardo Lima (Etrunko)" <etrunko@redhat.com>
Date: Thu, 18 May 2017 16:45:37 -0300
Subject: [PATCH] Introduce auxiliary function
ovirt_sub_collection_new_from_resource()

This function eliminates duplication of code used to create a
subcollection from a resource. Users are updated accordingly.

Signed-off-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
---
govirt/ovirt-api.c | 50 +++++++++++--------------------
govirt/ovirt-collection-private.h | 5 ++++
govirt/ovirt-collection.c | 15 ++++++++++
govirt/ovirt-storage-domain.c | 18 ++++-------
govirt/ovirt-vm.c | 18 ++++-------
5 files changed, 50 insertions(+), 56 deletions(-)

diff --git a/govirt/ovirt-api.c b/govirt/ovirt-api.c
index 001ee42..37c0935 100644
--- a/govirt/ovirt-api.c
+++ b/govirt/ovirt-api.c
@@ -123,18 +123,14 @@ OvirtApi *ovirt_api_new(void)
*/
OvirtCollection *ovirt_api_get_vms(OvirtApi *api)
{
- const char *href;
-
g_return_val_if_fail(OVIRT_IS_API(api), NULL);

- if (api->priv->vms != NULL)
- return api->priv->vms;
-
- href = ovirt_resource_get_sub_collection(OVIRT_RESOURCE(api), "vms");
- if (href == NULL)
- return NULL;
-
- api->priv->vms = ovirt_collection_new(href, "vms", OVIRT_TYPE_VM, "vm");
+ if (api->priv->vms == NULL)
+ api->priv->vms = ovirt_sub_collection_new_from_resource(OVIRT_RESOURCE(api),
+ "vms",
+ "vms",
+ OVIRT_TYPE_VM,
+ "vm");

return api->priv->vms;
}
@@ -151,18 +147,14 @@ OvirtCollection *ovirt_api_get_vms(OvirtApi *api)
*/
OvirtCollection *ovirt_api_get_vm_pools(OvirtApi *api)
{
- const char *href;
-
g_return_val_if_fail(OVIRT_IS_API(api), NULL);

- if (api->priv->vm_pools != NULL)
- return api->priv->vm_pools;
-
- href = ovirt_resource_get_sub_collection(OVIRT_RESOURCE(api), "vmpools");
- if (href == NULL)
- return NULL;
-
- api->priv->vm_pools = ovirt_collection_new(href, "vmpools", OVIRT_TYPE_VM_POOL, "vmpool");
+ if (api->priv->vm_pools == NULL)
+ api->priv->vm_pools = ovirt_sub_collection_new_from_resource(OVIRT_RESOURCE(api),
+ "vmpools",
+ "vmpools",
+ OVIRT_TYPE_VM_POOL,
+ "vmpool");

return api->priv->vm_pools;
}
@@ -180,20 +172,14 @@ OvirtCollection *ovirt_api_get_vm_pools(OvirtApi *api)
*/
OvirtCollection *ovirt_api_get_storage_domains(OvirtApi *api)
{
- const char *href;
-
g_return_val_if_fail(OVIRT_IS_API(api), NULL);

- if (api->priv->storage_domains != NULL)
- return api->priv->storage_domains;
-
- href = ovirt_resource_get_sub_collection(OVIRT_RESOURCE(api), "storagedomains");
- if (href == NULL)
- return NULL;
-
- api->priv->storage_domains = ovirt_collection_new(href, "storage_domains",
- OVIRT_TYPE_STORAGE_DOMAIN,
- "storage_domain");
+ if (api->priv->storage_domains == NULL)
+ api->priv->storage_domains = ovirt_sub_collection_new_from_resource(OVIRT_RESOURCE(api),
+ "storagedomains",
+ "storage_domains",
+ OVIRT_TYPE_STORAGE_DOMAIN,
+ "storage_domain");

return api->priv->storage_domains;
}
diff --git a/govirt/ovirt-collection-private.h b/govirt/ovirt-collection-private.h
index 5bc294f..d955fc6 100644
--- a/govirt/ovirt-collection-private.h
+++ b/govirt/ovirt-collection-private.h
@@ -41,6 +41,11 @@ OvirtCollection *ovirt_collection_new_from_xml(RestXmlNode *root_node,
GType resource_type,
const char *resource_name,
GError **error);
+OvirtCollection *ovirt_sub_collection_new_from_resource(OvirtResource *resource,
+ const char *href,
+ const char *collection_name,
+ GType resource_type,
+ const char *resource_name);

G_END_DECLS

diff --git a/govirt/ovirt-collection.c b/govirt/ovirt-collection.c
index a3b0f3f..6ec1c6e 100644
--- a/govirt/ovirt-collection.c
+++ b/govirt/ovirt-collection.c
@@ -344,6 +344,21 @@ OvirtCollection *ovirt_collection_new_from_xml(RestXmlNode *root_node,
}


+OvirtCollection *ovirt_sub_collection_new_from_resource(OvirtResource *resource,
+ const char *href,
+ const char *collection_name,
+ GType resource_type,
+ const char *resource_name)
+{
+ const char *link = ovirt_resource_get_sub_collection(resource, href);
+
+ if (link == NULL)
+ return NULL;
+
+ return ovirt_collection_new(link, collection_name, resource_type, resource_name);
+}
+
+
/**
* ovirt_collection_fetch:
* @collection: a #OvirtCollection
diff --git a/govirt/ovirt-storage-domain.c b/govirt/ovirt-storage-domain.c
index 0582203..38c4a62 100644
--- a/govirt/ovirt-storage-domain.c
+++ b/govirt/ovirt-storage-domain.c
@@ -317,20 +317,14 @@ OvirtStorageDomain *ovirt_storage_domain_new(void)
*/
OvirtCollection *ovirt_storage_domain_get_files(OvirtStorageDomain *domain)
{
- const char *href;
-
g_return_val_if_fail(OVIRT_IS_STORAGE_DOMAIN(domain), NULL);

- if (domain->priv->files != NULL)
- return domain->priv->files;
-
- href = ovirt_resource_get_sub_collection(OVIRT_RESOURCE(domain), "files");
- if (href == NULL)
- return NULL;
-
- domain->priv->files = ovirt_collection_new(href, "files",
- OVIRT_TYPE_RESOURCE,
- "file");
+ if (domain->priv->files == NULL)
+ domain->priv->files = ovirt_sub_collection_new_from_resource(OVIRT_RESOURCE(domain),
+ "files",
+ "files",
+ OVIRT_TYPE_RESOURCE,
+ "file");

return domain->priv->files;
}
diff --git a/govirt/ovirt-vm.c b/govirt/ovirt-vm.c
index 9a07c2f..3d64649 100644
--- a/govirt/ovirt-vm.c
+++ b/govirt/ovirt-vm.c
@@ -329,20 +329,14 @@ gboolean ovirt_vm_refresh_finish(OvirtVm *vm,
*/
OvirtCollection *ovirt_vm_get_cdroms(OvirtVm *vm)
{
- const char *href;
-
g_return_val_if_fail(OVIRT_IS_VM(vm), NULL);

- if (vm->priv->cdroms != NULL)
- return vm->priv->cdroms;
-
- href = ovirt_resource_get_sub_collection(OVIRT_RESOURCE(vm), "cdroms");
- if (href == NULL)
- return NULL;
-
- vm->priv->cdroms = ovirt_collection_new(href, "cdroms",
- OVIRT_TYPE_CDROM,
- "cdrom");
+ if (vm->priv->cdroms == NULL)
+ vm->priv->cdroms = ovirt_sub_collection_new_from_resource(OVIRT_RESOURCE(vm),
+ "cdroms",
+ "cdroms",
+ OVIRT_TYPE_CDROM,
+ "cdrom");

return vm->priv->cdroms;
}

199
SOURCES/0015-New-API-functions-to-enable-search-queries-of-collec.patch

@ -0,0 +1,199 @@ @@ -0,0 +1,199 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: "Eduardo Lima (Etrunko)" <etrunko@redhat.com>
Date: Fri, 7 Apr 2017 16:25:46 -0300
Subject: [PATCH] New API functions to enable search queries of collections

Currently it is not possible to specify search query to optimize the
collections returned by the REST API. It is necessary to retrieve and
parse the full results and then iterate over the data to find what you
are really looking for.

This patch introduces the search functionality for the APIs that are
currently supported, improving bandwidth usage and also the need to
iterate over the results.

Like the previous patch, this patch also introduces an auxiliary
function in ovirt-collection to retrieve a sub-collection with a search
query.

Signed-off-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
---
govirt/govirt.sym | 4 +++
govirt/ovirt-api.c | 60 +++++++++++++++++++++++++++++++
govirt/ovirt-api.h | 3 ++
govirt/ovirt-collection-private.h | 6 ++++
govirt/ovirt-collection.c | 31 ++++++++++++++++
5 files changed, 104 insertions(+)

diff --git a/govirt/govirt.sym b/govirt/govirt.sym
index 8371779..d02e77f 100644
--- a/govirt/govirt.sym
+++ b/govirt/govirt.sym
@@ -105,6 +105,10 @@ GOVIRT_0.3.2 {
ovirt_resource_delete;
ovirt_resource_delete_async;
ovirt_resource_delete_finish;
+
+ ovirt_api_search_storage_domains;
+ ovirt_api_search_vms;
+ ovirt_api_search_vm_pools;
} GOVIRT_0.3.1;

GOVIRT_0.3.4 {
diff --git a/govirt/ovirt-api.c b/govirt/ovirt-api.c
index 37c0935..ca3fdcf 100644
--- a/govirt/ovirt-api.c
+++ b/govirt/ovirt-api.c
@@ -135,6 +135,26 @@ OvirtCollection *ovirt_api_get_vms(OvirtApi *api)
return api->priv->vms;
}

+/**
+ * ovirt_api_search_vms:
+ * @api: a #OvirtApi
+ * @query: search query
+ *
+ * Return value: (transfer full):
+ */
+OvirtCollection *ovirt_api_search_vms(OvirtApi *api, const char *query)
+{
+ g_return_val_if_fail(OVIRT_IS_API(api), NULL);
+
+ return ovirt_sub_collection_new_from_resource_search(OVIRT_RESOURCE(api),
+ "vms/search",
+ "vms",
+ OVIRT_TYPE_VM,
+ "vm",
+ query);
+}
+
+
/**
* ovirt_api_get_vm_pools:
* @api: a #OvirtApi
@@ -160,6 +180,26 @@ OvirtCollection *ovirt_api_get_vm_pools(OvirtApi *api)
}


+/**
+ * ovirt_api_search_vm_pools:
+ * @api: a #OvirtApi
+ * @query: search query
+ *
+ * Return value: (transfer full):
+ */
+OvirtCollection *ovirt_api_search_vm_pools(OvirtApi *api, const char *query)
+{
+ g_return_val_if_fail(OVIRT_IS_API(api), NULL);
+
+ return ovirt_sub_collection_new_from_resource_search(OVIRT_RESOURCE(api),
+ "vmpools/search",
+ "vmpools",
+ OVIRT_TYPE_VM_POOL,
+ "vmpool",
+ query);
+}
+
+
/**
* ovirt_api_get_storage_domains:
* @api: a #OvirtApi
@@ -183,3 +223,23 @@ OvirtCollection *ovirt_api_get_storage_domains(OvirtApi *api)

return api->priv->storage_domains;
}
+
+
+/**
+ * ovirt_api_search_storage_domains:
+ * @api: a #OvirtApi
+ * @query: search query
+ *
+ * Return value: (transfer full):
+ */
+OvirtCollection *ovirt_api_search_storage_domains(OvirtApi *api, const char *query)
+{
+ g_return_val_if_fail(OVIRT_IS_API(api), NULL);
+
+ return ovirt_sub_collection_new_from_resource_search(OVIRT_RESOURCE(api),
+ "storagedomains/search",
+ "storage_domains",
+ OVIRT_TYPE_STORAGE_DOMAIN,
+ "storage_domain",
+ query);
+}
diff --git a/govirt/ovirt-api.h b/govirt/ovirt-api.h
index 5f0d4e9..1bf6c02 100644
--- a/govirt/ovirt-api.h
+++ b/govirt/ovirt-api.h
@@ -62,8 +62,11 @@ GType ovirt_api_get_type(void);
OvirtApi *ovirt_api_new(void);

OvirtCollection *ovirt_api_get_storage_domains(OvirtApi *api);
+OvirtCollection *ovirt_api_search_storage_domains(OvirtApi *api, const char *query);
OvirtCollection *ovirt_api_get_vms(OvirtApi *api);
+OvirtCollection *ovirt_api_search_vms(OvirtApi *api, const char *query);
OvirtCollection *ovirt_api_get_vm_pools(OvirtApi *api);
+OvirtCollection *ovirt_api_search_vm_pools(OvirtApi *api, const char *query);

G_END_DECLS

diff --git a/govirt/ovirt-collection-private.h b/govirt/ovirt-collection-private.h
index d955fc6..cf7e603 100644
--- a/govirt/ovirt-collection-private.h
+++ b/govirt/ovirt-collection-private.h
@@ -46,6 +46,12 @@ OvirtCollection *ovirt_sub_collection_new_from_resource(OvirtResource *resource,
const char *collection_name,
GType resource_type,
const char *resource_name);
+OvirtCollection *ovirt_sub_collection_new_from_resource_search(OvirtResource *resource,
+ const char *href,
+ const char *collection_name,
+ GType resource_type,
+ const char *resource_name,
+ const char *query);

G_END_DECLS

diff --git a/govirt/ovirt-collection.c b/govirt/ovirt-collection.c
index 6ec1c6e..d36d750 100644
--- a/govirt/ovirt-collection.c
+++ b/govirt/ovirt-collection.c
@@ -358,6 +358,37 @@ OvirtCollection *ovirt_sub_collection_new_from_resource(OvirtResource *resource,
return ovirt_collection_new(link, collection_name, resource_type, resource_name);
}

+OvirtCollection *ovirt_sub_collection_new_from_resource_search(OvirtResource *resource,
+ const char *href,
+ const char *collection_name,
+ GType resource_type,
+ const char *resource_name,
+ const char *query)
+{
+ const char *link;
+ char *substr;
+ gchar *link_query, *escaped_query;
+ OvirtCollection *collection;
+
+ link = ovirt_resource_get_sub_collection(resource, href);
+ if (link == NULL)
+ return NULL;
+
+ /* link is will be something like "/ovirt-engine/api/vms?search={query}", so
+ * we need to strip out {query} substring.
+ */
+ substr = g_strrstr(link, "{query}");
+ if (substr != NULL)
+ *substr = '\0';
+
+ escaped_query = g_uri_escape_string(query, NULL, FALSE);
+ link_query = g_strconcat(link, escaped_query, NULL);
+ collection = ovirt_collection_new(link_query, collection_name, resource_type, resource_name);
+ g_free(escaped_query);
+ g_free(link_query);
+
+ return collection;
+}

/**
* ovirt_collection_fetch:

85
SOURCES/0016-Introduce-ovirt_resource_new-functions.patch

@ -0,0 +1,85 @@ @@ -0,0 +1,85 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: "Eduardo Lima (Etrunko)" <etrunko@redhat.com>
Date: Thu, 13 Jul 2017 16:56:34 -0300
Subject: [PATCH] Introduce ovirt_resource_new*() functions

These functions should be used to replace usage of g_initable_new()
around the codebase, as it avoids code duplication by combining all
different ways of creating a resource in a single function.

Signed-off-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
---
govirt/ovirt-resource-private.h | 4 +++
govirt/ovirt-resource.c | 47 +++++++++++++++++++++++++++++++++
2 files changed, 51 insertions(+)

diff --git a/govirt/ovirt-resource-private.h b/govirt/ovirt-resource-private.h
index ff4e705..ef47557 100644
--- a/govirt/ovirt-resource-private.h
+++ b/govirt/ovirt-resource-private.h
@@ -27,6 +27,10 @@

G_BEGIN_DECLS

+OvirtResource *ovirt_resource_new(GType type);
+OvirtResource *ovirt_resource_new_from_id(GType type, const char *id, const char *href);
+OvirtResource *ovirt_resource_new_from_xml(GType type, RestXmlNode *node, GError **error);
+
const char *ovirt_resource_get_action(OvirtResource *resource,
const char *action);
char *ovirt_resource_to_xml(OvirtResource *resource);
diff --git a/govirt/ovirt-resource.c b/govirt/ovirt-resource.c
index 7f79ab7..1413a77 100644
--- a/govirt/ovirt-resource.c
+++ b/govirt/ovirt-resource.c
@@ -1065,3 +1065,50 @@ gboolean ovirt_resource_delete_finish(OvirtResource *resource,

return ovirt_rest_call_finish(result, err);
}
+
+
+static OvirtResource *ovirt_resource_new_valist(GType type, GError **error, const char *prop_name, ...)
+{
+ gpointer resource;
+ va_list var_args;
+ GError *local_error = NULL;
+
+ g_return_val_if_fail(g_type_is_a(type, OVIRT_TYPE_RESOURCE), NULL);
+
+ va_start(var_args, prop_name);
+ resource = g_initable_new_valist(type, prop_name, var_args, NULL, &local_error);
+ va_end(var_args);
+
+ if (local_error != NULL) {
+ g_warning("Failed to create resource of type %s: %s", g_type_name(type), local_error->message);
+ g_propagate_error(error, local_error);
+ }
+
+ return OVIRT_RESOURCE(resource);
+}
+
+
+G_GNUC_INTERNAL
+OvirtResource *ovirt_resource_new(GType type)
+{
+ return ovirt_resource_new_valist(type, NULL, NULL);
+}
+
+
+G_GNUC_INTERNAL
+OvirtResource *ovirt_resource_new_from_id(GType type, const char *id, const char *href)
+{
+ g_return_val_if_fail(id != NULL, NULL);
+ g_return_val_if_fail(href != NULL, NULL);
+
+ return ovirt_resource_new_valist(type, NULL, "guid", id, "href", href, NULL);
+}
+
+
+G_GNUC_INTERNAL
+OvirtResource *ovirt_resource_new_from_xml(GType type, RestXmlNode *node, GError **error)
+{
+ g_return_val_if_fail(node != NULL, NULL);
+
+ return ovirt_resource_new_valist(type, error, "xml-node", node, NULL);
+}

144
SOURCES/0017-Use-ovirt_resource_new-functions-instead-of-g_initab.patch

@ -0,0 +1,144 @@ @@ -0,0 +1,144 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: "Eduardo Lima (Etrunko)" <etrunko@redhat.com>
Date: Thu, 13 Jul 2017 16:58:28 -0300
Subject: [PATCH] Use ovirt_resource_new* functions instead of g_initable_new

This patch also fix some functions that were supposed to be tagged as
G_GNUC_INTERNAL.

Signed-off-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
---
govirt/ovirt-api.c | 8 +++++---
govirt/ovirt-collection.c | 4 +---
govirt/ovirt-storage-domain.c | 11 ++---------
govirt/ovirt-utils.c | 3 ++-
govirt/ovirt-vm-pool.c | 3 ++-
govirt/ovirt-vm.c | 8 +++++---
6 files changed, 17 insertions(+), 20 deletions(-)

diff --git a/govirt/ovirt-api.c b/govirt/ovirt-api.c
index ca3fdcf..93dc3d5 100644
--- a/govirt/ovirt-api.c
+++ b/govirt/ovirt-api.c
@@ -98,16 +98,18 @@ static void ovirt_api_init(G_GNUC_UNUSED OvirtApi *api)
api->priv = OVIRT_API_GET_PRIVATE(api);
}

+G_GNUC_INTERNAL
OvirtApi *ovirt_api_new_from_xml(RestXmlNode *node, GError **error)
{
- return OVIRT_API(g_initable_new(OVIRT_TYPE_API, NULL, error,
- "xml-node", node, NULL));
+ OvirtResource *api = ovirt_resource_new_from_xml(OVIRT_TYPE_API, node, error);
+ return OVIRT_API(api);
}


OvirtApi *ovirt_api_new(void)
{
- return OVIRT_API(g_initable_new(OVIRT_TYPE_API, NULL, NULL, NULL));
+ OvirtResource *api = ovirt_resource_new(OVIRT_TYPE_API);
+ return OVIRT_API(api);
}


diff --git a/govirt/ovirt-collection.c b/govirt/ovirt-collection.c
index d36d750..8008903 100644
--- a/govirt/ovirt-collection.c
+++ b/govirt/ovirt-collection.c
@@ -235,9 +235,7 @@ ovirt_collection_new_resource_from_xml(OvirtCollection *collection,
RestXmlNode *node,
GError **error)
{
- return OVIRT_RESOURCE(g_initable_new(collection->priv->resource_type,
- NULL, error,
- "xml-node", node , NULL));
+ return ovirt_resource_new_from_xml(collection->priv->resource_type, node, error);
}


diff --git a/govirt/ovirt-storage-domain.c b/govirt/ovirt-storage-domain.c
index 38c4a62..e255565 100644
--- a/govirt/ovirt-storage-domain.c
+++ b/govirt/ovirt-storage-domain.c
@@ -285,20 +285,13 @@ G_GNUC_INTERNAL
OvirtStorageDomain *ovirt_storage_domain_new_from_xml(RestXmlNode *node,
GError **error)
{
- GObject *domain;
-
- domain = g_initable_new(OVIRT_TYPE_STORAGE_DOMAIN, NULL, error,
- "xml-node", node, NULL);
-
+ OvirtResource *domain = ovirt_resource_new_from_xml(OVIRT_TYPE_STORAGE_DOMAIN, node, error);
return OVIRT_STORAGE_DOMAIN(domain);
}

OvirtStorageDomain *ovirt_storage_domain_new(void)
{
- GObject *domain;
-
- domain = g_initable_new(OVIRT_TYPE_STORAGE_DOMAIN, NULL, NULL, NULL);
-
+ OvirtResource *domain = ovirt_resource_new(OVIRT_TYPE_STORAGE_DOMAIN);
return OVIRT_STORAGE_DOMAIN(domain);
}

diff --git a/govirt/ovirt-utils.c b/govirt/ovirt-utils.c
index a200e48..1898862 100644
--- a/govirt/ovirt-utils.c
+++ b/govirt/ovirt-utils.c
@@ -32,6 +32,7 @@

#include "ovirt-error.h"
#include "ovirt-resource.h"
+#include "ovirt-resource-private.h"

RestXmlNode *
ovirt_rest_xml_node_from_call(RestProxyCall *call)
@@ -142,7 +143,7 @@ _set_property_value_from_type(GValue *value,
const char *value_str;

if (g_type_is_a(type, OVIRT_TYPE_RESOURCE)) {
- GObject *resource_value = g_initable_new(type, NULL, NULL, "xml-node", node, NULL);
+ OvirtResource *resource_value = ovirt_resource_new_from_xml(type, node, NULL);
g_value_set_object(value, resource_value);
goto end;
} else if (g_type_is_a(type, G_TYPE_STRV)) {
diff --git a/govirt/ovirt-vm-pool.c b/govirt/ovirt-vm-pool.c
index 3187a8c..9d0d742 100644
--- a/govirt/ovirt-vm-pool.c
+++ b/govirt/ovirt-vm-pool.c
@@ -168,7 +168,8 @@ static void ovirt_vm_pool_init(G_GNUC_UNUSED OvirtVmPool *vm_pool)

OvirtVmPool *ovirt_vm_pool_new(void)
{
- return OVIRT_VM_POOL(g_initable_new(OVIRT_TYPE_VM_POOL, NULL, NULL, NULL));
+ OvirtResource *vm_pool = ovirt_resource_new(OVIRT_TYPE_VM_POOL);
+ return OVIRT_VM_POOL(vm_pool);
}


diff --git a/govirt/ovirt-vm.c b/govirt/ovirt-vm.c
index 3d64649..806b5f3 100644
--- a/govirt/ovirt-vm.c
+++ b/govirt/ovirt-vm.c
@@ -163,15 +163,17 @@ static void ovirt_vm_init(G_GNUC_UNUSED OvirtVm *vm)
vm->priv = OVIRT_VM_GET_PRIVATE(vm);
}

+G_GNUC_INTERNAL
OvirtVm *ovirt_vm_new_from_xml(RestXmlNode *node, GError **error)
{
- return OVIRT_VM(g_initable_new(OVIRT_TYPE_VM, NULL, error,
- "xml-node", node, NULL));
+ OvirtResource *vm = ovirt_resource_new_from_xml(OVIRT_TYPE_VM, node, error);
+ return OVIRT_VM(vm);
}

OvirtVm *ovirt_vm_new(void)
{
- return OVIRT_VM(g_initable_new(OVIRT_TYPE_VM, NULL, NULL, NULL));
+ OvirtResource *vm = ovirt_resource_new(OVIRT_TYPE_VM);
+ return OVIRT_VM(vm);
}

135
SOURCES/0018-Move-resource-type-definitions-to-ovirt-types.h.patch

@ -0,0 +1,135 @@ @@ -0,0 +1,135 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: "Eduardo Lima (Etrunko)" <etrunko@redhat.com>
Date: Thu, 13 Jul 2017 16:43:53 -0300
Subject: [PATCH] Move resource type definitions to ovirt-types.h

With recently added ovirt_resource_new* functions, it is now possible to
create any type of resource, being only necessary to pass the type as
argument.

In order to avoid interdependencies between objects, we need a common
place for definition of the resource types. For instance, it should be
possible to access a OvirtHost from a OvirtVm and vice-versa.

Signed-off-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
---
govirt/ovirt-api.h | 1 -
govirt/ovirt-cdrom.h | 1 -
govirt/ovirt-collection.h | 1 -
govirt/ovirt-storage-domain.h | 1 -
govirt/ovirt-types.h | 7 +++++++
govirt/ovirt-vm-display.h | 2 +-
govirt/ovirt-vm-pool.h | 1 -
govirt/ovirt-vm.h | 1 -
8 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/govirt/ovirt-api.h b/govirt/ovirt-api.h
index 1bf6c02..d511d70 100644
--- a/govirt/ovirt-api.h
+++ b/govirt/ovirt-api.h
@@ -37,7 +37,6 @@ G_BEGIN_DECLS
#define OVIRT_IS_API_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), OVIRT_TYPE_API))
#define OVIRT_API_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), OVIRT_TYPE_API, OvirtApiClass))

-typedef struct _OvirtApi OvirtApi;
typedef struct _OvirtApiPrivate OvirtApiPrivate;
typedef struct _OvirtApiClass OvirtApiClass;

diff --git a/govirt/ovirt-cdrom.h b/govirt/ovirt-cdrom.h
index a268d01..a43d85d 100644
--- a/govirt/ovirt-cdrom.h
+++ b/govirt/ovirt-cdrom.h
@@ -36,7 +36,6 @@ G_BEGIN_DECLS
#define OVIRT_IS_CDROM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), OVIRT_TYPE_CDROM))
#define OVIRT_CDROM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), OVIRT_TYPE_CDROM, OvirtCdromClass))

-typedef struct _OvirtCdrom OvirtCdrom;
typedef struct _OvirtCdromPrivate OvirtCdromPrivate;
typedef struct _OvirtCdromClass OvirtCdromClass;

diff --git a/govirt/ovirt-collection.h b/govirt/ovirt-collection.h
index b41d269..af630e1 100644
--- a/govirt/ovirt-collection.h
+++ b/govirt/ovirt-collection.h
@@ -36,7 +36,6 @@ G_BEGIN_DECLS
#define OVIRT_IS_COLLECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), OVIRT_TYPE_COLLECTION))
#define OVIRT_COLLECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), OVIRT_TYPE_COLLECTION, OvirtCollectionClass))

-typedef struct _OvirtCollection OvirtCollection;
typedef struct _OvirtCollectionPrivate OvirtCollectionPrivate;
typedef struct _OvirtCollectionClass OvirtCollectionClass;

diff --git a/govirt/ovirt-storage-domain.h b/govirt/ovirt-storage-domain.h
index 79f1741..dd7b593 100644
--- a/govirt/ovirt-storage-domain.h
+++ b/govirt/ovirt-storage-domain.h
@@ -61,7 +61,6 @@ typedef enum {
OVIRT_STORAGE_DOMAIN_TYPE_IMAGE,
} OvirtStorageDomainType;

-typedef struct _OvirtStorageDomain OvirtStorageDomain;
typedef struct _OvirtStorageDomainPrivate OvirtStorageDomainPrivate;
typedef struct _OvirtStorageDomainClass OvirtStorageDomainClass;

diff --git a/govirt/ovirt-types.h b/govirt/ovirt-types.h
index 6e83368..c89521b 100644
--- a/govirt/ovirt-types.h
+++ b/govirt/ovirt-types.h
@@ -25,7 +25,14 @@

G_BEGIN_DECLS

+typedef struct _OvirtApi OvirtApi;
+typedef struct _OvirtCdrom OvirtCdrom;
+typedef struct _OvirtCollection OvirtCollection;
typedef struct _OvirtProxy OvirtProxy;
+typedef struct _OvirtStorageDomain OvirtStorageDomain;
+typedef struct _OvirtVmDisplay OvirtVmDisplay;
+typedef struct _OvirtVmPool OvirtVmPool;
+typedef struct _OvirtVm OvirtVm;

G_END_DECLS

diff --git a/govirt/ovirt-vm-display.h b/govirt/ovirt-vm-display.h
index 2b8a86d..f7eb310 100644
--- a/govirt/ovirt-vm-display.h
+++ b/govirt/ovirt-vm-display.h
@@ -23,6 +23,7 @@
#define __OVIRT_VM_DISPLAY_H__

#include <glib-object.h>
+#include <govirt/ovirt-types.h>

G_BEGIN_DECLS

@@ -33,7 +34,6 @@ G_BEGIN_DECLS
#define OVIRT_IS_VM_DISPLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), OVIRT_TYPE_VM_DISPLAY))
#define OVIRT_VM_DISPLAY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), OVIRT_TYPE_VM_DISPLAY, OvirtVmDisplayClass))

-typedef struct _OvirtVmDisplay OvirtVmDisplay;
typedef struct _OvirtVmDisplayPrivate OvirtVmDisplayPrivate;
typedef struct _OvirtVmDisplayClass OvirtVmDisplayClass;

diff --git a/govirt/ovirt-vm-pool.h b/govirt/ovirt-vm-pool.h
index ee2f55c..10e7be7 100644
--- a/govirt/ovirt-vm-pool.h
+++ b/govirt/ovirt-vm-pool.h
@@ -35,7 +35,6 @@ G_BEGIN_DECLS
#define OVIRT_IS_VM_POOL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), OVIRT_TYPE_VM_POOL))
#define OVIRT_VM_POOL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), OVIRT_TYPE_VM_POOL, OvirtVmPoolClass))

-typedef struct _OvirtVmPool OvirtVmPool;
typedef struct _OvirtVmPoolPrivate OvirtVmPoolPrivate;
typedef struct _OvirtVmPoolClass OvirtVmPoolClass;

diff --git a/govirt/ovirt-vm.h b/govirt/ovirt-vm.h
index 10910e3..1e6c7ad 100644
--- a/govirt/ovirt-vm.h
+++ b/govirt/ovirt-vm.h
@@ -41,7 +41,6 @@ G_BEGIN_DECLS
#define OVIRT_IS_VM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), OVIRT_TYPE_VM))
#define OVIRT_VM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), OVIRT_TYPE_VM, OvirtVmClass))

-typedef struct _OvirtVm OvirtVm;
typedef struct _OvirtVmPrivate OvirtVmPrivate;
typedef struct _OvirtVmClass OvirtVmClass;

515
SOURCES/0019-Initial-support-for-hosts.patch

@ -0,0 +1,515 @@ @@ -0,0 +1,515 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: "Eduardo Lima (Etrunko)" <etrunko@redhat.com>
Date: Tue, 11 Apr 2017 21:47:44 -0300
Subject: [PATCH] Initial support for hosts

At the moment, we only care about the information about the cluster the
host is part of, and the list of the vms associated with it.

Signed-off-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
---
govirt/Makefile.am | 3 +
govirt/govirt-private.h | 1 +
govirt/govirt.sym | 11 ++
govirt/ovirt-api.c | 47 ++++++++
govirt/ovirt-api.h | 2 +
govirt/ovirt-host-private.h | 37 +++++++
govirt/ovirt-host.c | 214 ++++++++++++++++++++++++++++++++++++
govirt/ovirt-host.h | 66 +++++++++++
govirt/ovirt-types.h | 1 +
9 files changed, 382 insertions(+)
create mode 100644 govirt/ovirt-host-private.h
create mode 100644 govirt/ovirt-host.c
create mode 100644 govirt/ovirt-host.h

diff --git a/govirt/Makefile.am b/govirt/Makefile.am
index e905f1f..c62a1d6 100644
--- a/govirt/Makefile.am
+++ b/govirt/Makefile.am
@@ -21,6 +21,7 @@ libgovirt_la_HEADERS = \
ovirt-cdrom.h \
ovirt-collection.h \
ovirt-error.h \
+ ovirt-host.h \
ovirt-options.h \
ovirt-proxy.h \
ovirt-resource.h \
@@ -38,6 +39,7 @@ noinst_HEADERS = \
ovirt-action-rest-call.h \
ovirt-api-private.h \
ovirt-collection-private.h \
+ ovirt-host-private.h \
ovirt-proxy-private.h \
ovirt-resource-private.h \
ovirt-rest-call.h \
@@ -54,6 +56,7 @@ libgovirt_la_SOURCES = \
ovirt-cdrom.c \
ovirt-collection.c \
ovirt-error.c \
+ ovirt-host.c \
ovirt-options.c \
ovirt-proxy.c \
ovirt-proxy-deprecated.c \
diff --git a/govirt/govirt-private.h b/govirt/govirt-private.h
index 972ebac..b51feb3 100644
--- a/govirt/govirt-private.h
+++ b/govirt/govirt-private.h
@@ -26,6 +26,7 @@
#include <govirt/ovirt-api-private.h>
#include <govirt/ovirt-collection-private.h>
#include <govirt/ovirt-enum-types-private.h>
+#include <govirt/ovirt-host-private.h>
#include <govirt/ovirt-proxy-private.h>
#include <govirt/ovirt-resource-private.h>
#include <govirt/ovirt-resource-rest-call.h>
diff --git a/govirt/govirt.sym b/govirt/govirt.sym
index d02e77f..6dc8159 100644
--- a/govirt/govirt.sym
+++ b/govirt/govirt.sym
@@ -109,6 +109,17 @@ GOVIRT_0.3.2 {
ovirt_api_search_storage_domains;
ovirt_api_search_vms;
ovirt_api_search_vm_pools;
+
+ ovirt_api_get_hosts;
+
+ ovirt_api_search_hosts;
+ ovirt_api_search_storage_domains;
+ ovirt_api_search_vms;
+ ovirt_api_search_vm_pools;
+
+ ovirt_host_get_type;
+ ovirt_host_get_vms;
+ ovirt_host_new;
} GOVIRT_0.3.1;

GOVIRT_0.3.4 {
diff --git a/govirt/ovirt-api.c b/govirt/ovirt-api.c
index 93dc3d5..fef04ba 100644
--- a/govirt/ovirt-api.c
+++ b/govirt/ovirt-api.c
@@ -41,6 +41,7 @@


struct _OvirtApiPrivate {
+ OvirtCollection *hosts;
OvirtCollection *storage_domains;
OvirtCollection *vms;
OvirtCollection *vm_pools;
@@ -73,6 +74,7 @@ static void ovirt_api_dispose(GObject *object)
{
OvirtApi *api = OVIRT_API(object);

+ g_clear_object(&api->priv->hosts);
g_clear_object(&api->priv->storage_domains);
g_clear_object(&api->priv->vms);
g_clear_object(&api->priv->vm_pools);
@@ -245,3 +247,48 @@ OvirtCollection *ovirt_api_search_storage_domains(OvirtApi *api, const char *que
"storage_domain",
query);
}
+
+
+/**
+ * ovirt_api_get_hosts:
+ * @api: a #OvirtApi
+ *
+ * This method does not initiate any network activity, the collection
+ * must be fetched with ovirt_collection_fetch() before having up-to-date
+ * content.
+ *
+ * Return value: (transfer none):
+ */
+OvirtCollection *ovirt_api_get_hosts(OvirtApi *api)
+{
+ g_return_val_if_fail(OVIRT_IS_API(api), NULL);
+
+ if (api->priv->hosts == NULL)
+ api->priv->hosts = ovirt_sub_collection_new_from_resource(OVIRT_RESOURCE(api),
+ "hosts",
+ "hosts",
+ OVIRT_TYPE_HOST,
+ "host");
+
+ return api->priv->hosts;
+}
+
+
+/**
+ * ovirt_api_search_hosts:
+ * @api: a #OvirtApi
+ * @query: search query
+ *
+ * Return value: (transfer none):
+ */
+OvirtCollection *ovirt_api_search_hosts(OvirtApi *api, const char *query)
+{
+ g_return_val_if_fail(OVIRT_IS_API(api), NULL);
+
+ return ovirt_sub_collection_new_from_resource_search(OVIRT_RESOURCE(api),
+ "hosts",
+ "hosts",
+ OVIRT_TYPE_HOST,
+ "host",
+ query);
+}
diff --git a/govirt/ovirt-api.h b/govirt/ovirt-api.h
index d511d70..c46e934 100644
--- a/govirt/ovirt-api.h
+++ b/govirt/ovirt-api.h
@@ -60,6 +60,8 @@ struct _OvirtApiClass
GType ovirt_api_get_type(void);
OvirtApi *ovirt_api_new(void);

+OvirtCollection *ovirt_api_get_hosts(OvirtApi *api);
+OvirtCollection *ovirt_api_search_hosts(OvirtApi *api, const char *query);
OvirtCollection *ovirt_api_get_storage_domains(OvirtApi *api);
OvirtCollection *ovirt_api_search_storage_domains(OvirtApi *api, const char *query);
OvirtCollection *ovirt_api_get_vms(OvirtApi *api);
diff --git a/govirt/ovirt-host-private.h b/govirt/ovirt-host-private.h
new file mode 100644
index 0000000..26587ea
--- /dev/null
+++ b/govirt/ovirt-host-private.h
@@ -0,0 +1,37 @@
+/*
+ * ovirt-host-private.h: oVirt host resource
+ *
+ * Copyright (C) 2017 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Author: Eduardo Lima (Etrunko) <etrunko@redhat.com>
+ */
+#ifndef __OVIRT_HOST_PRIVATE_H__
+#define __OVIRT_HOST_PRIVATE_H__
+
+#include <ovirt-host.h>
+#include <rest/rest-xml-node.h>
+
+G_BEGIN_DECLS
+
+OvirtHost *ovirt_host_new_from_id(const char *id,
+ const char *href);
+OvirtHost *ovirt_host_new_from_xml(RestXmlNode *node,
+ GError **error);
+
+G_END_DECLS
+
+#endif /* __OVIRT_HOST_PRIVATE_H__ */
diff --git a/govirt/ovirt-host.c b/govirt/ovirt-host.c
new file mode 100644
index 0000000..2df2a64
--- /dev/null
+++ b/govirt/ovirt-host.c
@@ -0,0 +1,214 @@
+/*
+ * ovirt-host.c: oVirt host handling
+ *
+ * Copyright (C) 2017 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Author: Eduardo Lima (Etrunko) <etrunko@redhat.com>
+ */
+
+#include <config.h>
+#include "ovirt-enum-types.h"
+#include "ovirt-host.h"
+#include "govirt-private.h"
+
+#define OVIRT_HOST_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), OVIRT_TYPE_HOST, OvirtHostPrivate))
+
+struct _OvirtHostPrivate {
+ gchar *cluster_href;
+ gchar *cluster_id;
+ OvirtCollection *vms;
+};
+
+G_DEFINE_TYPE(OvirtHost, ovirt_host, OVIRT_TYPE_RESOURCE);
+
+enum {
+ PROP_0,
+ PROP_CLUSTER_HREF,
+ PROP_CLUSTER_ID,
+};
+
+static void ovirt_host_get_property(GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ OvirtHost *host = OVIRT_HOST(object);
+
+ switch (prop_id) {
+ case PROP_CLUSTER_HREF:
+ g_value_set_string(value, host->priv->cluster_href);
+ break;
+ case PROP_CLUSTER_ID:
+ g_value_set_string(value, host->priv->cluster_id);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ }
+}
+
+static void ovirt_host_set_property(GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ OvirtHost *host = OVIRT_HOST(object);
+
+ switch (prop_id) {
+ case PROP_CLUSTER_HREF:
+ g_free(host->priv->cluster_href);
+ host->priv->cluster_href = g_value_dup_string(value);
+ break;
+ case PROP_CLUSTER_ID:
+ g_free(host->priv->cluster_id);
+ host->priv->cluster_id = g_value_dup_string(value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ }
+}
+
+
+static void
+ovirt_host_dispose(GObject *obj)
+{
+ OvirtHost *host = OVIRT_HOST(obj);
+
+ g_clear_pointer(&host->priv->cluster_href, g_free);
+ g_clear_pointer(&host->priv->cluster_id, g_free);
+ g_clear_object(&host->priv->vms);
+
+ G_OBJECT_CLASS(ovirt_host_parent_class)->dispose(obj);
+}
+
+
+static gboolean ovirt_host_init_from_xml(OvirtResource *resource,
+ RestXmlNode *node,
+ GError **error)
+{
+ OvirtResourceClass *parent_class;
+ OvirtXmlElement host_elements[] = {
+ { .prop_name = "cluster-href",
+ .type = G_TYPE_STRING,
+ .xml_path = "cluster",
+ .xml_attr = "href",
+ },
+ { .prop_name = "cluster-id",
+ .type = G_TYPE_STRING,
+ .xml_path = "cluster",
+ .xml_attr = "id",
+ },
+ { NULL , },
+ };
+
+ if (!ovirt_rest_xml_node_parse(node, G_OBJECT(resource), host_elements))
+ return FALSE;
+
+ parent_class = OVIRT_RESOURCE_CLASS(ovirt_host_parent_class);
+ return parent_class->init_from_xml(resource, node, error);
+}
+
+
+static void ovirt_host_class_init(OvirtHostClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS(klass);
+ OvirtResourceClass *resource_class = OVIRT_RESOURCE_CLASS(klass);
+ GParamSpec *param_spec;
+
+ g_type_class_add_private(klass, sizeof(OvirtHostPrivate));
+
+ resource_class->init_from_xml = ovirt_host_init_from_xml;
+ object_class->dispose = ovirt_host_dispose;
+ object_class->get_property = ovirt_host_get_property;
+ object_class->set_property = ovirt_host_set_property;
+
+ param_spec = g_param_spec_string("cluster-href",
+ "Cluster href",
+ "Cluster href for the Host",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property(object_class,
+ PROP_CLUSTER_HREF,
+ param_spec);
+
+ param_spec = g_param_spec_string("cluster-id",
+ "Cluster Id",
+ "Cluster Id for the Host",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property(object_class,
+ PROP_CLUSTER_ID,
+ param_spec);
+}
+
+static void ovirt_host_init(OvirtHost *host)
+{
+ host->priv = OVIRT_HOST_GET_PRIVATE(host);
+}
+
+G_GNUC_INTERNAL
+OvirtHost *ovirt_host_new_from_id(const char *id,
+ const char *href)
+{
+ OvirtResource *host = ovirt_resource_new_from_id(OVIRT_TYPE_HOST, id, href);
+ return OVIRT_HOST(host);
+}
+
+G_GNUC_INTERNAL
+OvirtHost *ovirt_host_new_from_xml(RestXmlNode *node,
+ GError **error)
+{
+ OvirtResource *host = ovirt_resource_new_from_xml(OVIRT_TYPE_HOST, node, error);
+ return OVIRT_HOST(host);
+}
+
+OvirtHost *ovirt_host_new(void)
+{
+ OvirtResource *host = ovirt_resource_new(OVIRT_TYPE_HOST);
+ return OVIRT_HOST(host);
+}
+
+/**
+ * ovirt_host_get_vms:
+ * @host: a #OvirtHost
+ *
+ * Gets a #OvirtCollection representing the list of remote vms from a
+ * host object. This method does not initiate any network
+ * activity, the remote vm list must be then be fetched using
+ * ovirt_collection_fetch() or ovirt_collection_fetch_async().
+ *
+ * Return value: (transfer none): a #OvirtCollection representing the list
+ * of vms associated with @host.
+ */
+OvirtCollection *ovirt_host_get_vms(OvirtHost *host)
+{
+ g_return_val_if_fail(OVIRT_IS_HOST(host), NULL);
+
+ if (host->priv->vms == NULL) {
+ OvirtCollection *collection;
+ collection = ovirt_sub_collection_new_from_resource(OVIRT_RESOURCE(host),
+ "vms",
+ "vms",
+ OVIRT_TYPE_VM,
+ "vm");
+ host->priv->vms = collection;
+ }
+
+ return host->priv->vms;
+}
diff --git a/govirt/ovirt-host.h b/govirt/ovirt-host.h
new file mode 100644
index 0000000..91441f6
--- /dev/null
+++ b/govirt/ovirt-host.h
@@ -0,0 +1,66 @@
+/*
+ * ovirt-host.h: oVirt host resource
+ *
+ * Copyright (C) 2017 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Author: Eduardo Lima (Etrunko) <etrunko@redhat.com>
+ */
+#ifndef __OVIRT_HOST_H__
+#define __OVIRT_HOST_H__
+
+#include <gio/gio.h>
+#include <glib-object.h>
+#include <govirt/ovirt-collection.h>
+#include <govirt/ovirt-resource.h>
+#include <govirt/ovirt-types.h>
+
+G_BEGIN_DECLS
+
+#define OVIRT_TYPE_HOST (ovirt_host_get_type ())
+#define OVIRT_HOST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), OVIRT_TYPE_HOST, OvirtHost))
+#define OVIRT_HOST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), OVIRT_TYPE_HOST, OvirtHostClass))
+#define OVIRT_IS_HOST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OVIRT_TYPE_HOST))
+#define OVIRT_IS_HOST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), OVIRT_TYPE_HOST))
+#define OVIRT_HOST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), OVIRT_TYPE_HOST, OvirtHostClass))
+
+typedef struct _OvirtHostPrivate OvirtHostPrivate;
+typedef struct _OvirtHostClass OvirtHostClass;
+
+struct _OvirtHost
+{
+ OvirtResource parent;
+
+ OvirtHostPrivate *priv;
+
+ /* Do not add fields to this struct */
+};
+
+struct _OvirtHostClass
+{
+ OvirtResourceClass parent_class;
+
+ gpointer padding[20];
+};
+
+GType ovirt_host_get_type(void);
+
+OvirtHost *ovirt_host_new(void);
+OvirtCollection *ovirt_host_get_vms(OvirtHost *host);
+
+G_END_DECLS
+
+#endif /* __OVIRT_HOST_H__ */
diff --git a/govirt/ovirt-types.h b/govirt/ovirt-types.h
index c89521b..42fc004 100644
--- a/govirt/ovirt-types.h
+++ b/govirt/ovirt-types.h
@@ -28,6 +28,7 @@ G_BEGIN_DECLS
typedef struct _OvirtApi OvirtApi;
typedef struct _OvirtCdrom OvirtCdrom;
typedef struct _OvirtCollection OvirtCollection;
+typedef struct _OvirtHost OvirtHost;
typedef struct _OvirtProxy OvirtProxy;
typedef struct _OvirtStorageDomain OvirtStorageDomain;
typedef struct _OvirtVmDisplay OvirtVmDisplay;

519
SOURCES/0020-Initial-support-for-clusters.patch

@ -0,0 +1,519 @@ @@ -0,0 +1,519 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: "Eduardo Lima (Etrunko)" <etrunko@redhat.com>
Date: Tue, 11 Apr 2017 21:51:14 -0300
Subject: [PATCH] Initial support for clusters

Like the previous commit, at the moment, we only care about the
information of the data center the cluster is part of, and the list of
the hosts associated with it.

Signed-off-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
---
govirt/Makefile.am | 3 +
govirt/govirt-private.h | 1 +
govirt/govirt.sym | 6 +
govirt/ovirt-api.c | 47 +++++++
govirt/ovirt-api.h | 2 +
govirt/ovirt-cluster-private.h | 37 ++++++
govirt/ovirt-cluster.c | 215 +++++++++++++++++++++++++++++++++
govirt/ovirt-cluster.h | 66 ++++++++++
govirt/ovirt-types.h | 1 +
9 files changed, 378 insertions(+)
create mode 100644 govirt/ovirt-cluster-private.h
create mode 100644 govirt/ovirt-cluster.c
create mode 100644 govirt/ovirt-cluster.h

diff --git a/govirt/Makefile.am b/govirt/Makefile.am
index c62a1d6..cf6b858 100644
--- a/govirt/Makefile.am
+++ b/govirt/Makefile.am
@@ -19,6 +19,7 @@ libgovirt_la_HEADERS = \
govirt.h \
ovirt-api.h \
ovirt-cdrom.h \
+ ovirt-cluster.h \
ovirt-collection.h \
ovirt-error.h \
ovirt-host.h \
@@ -38,6 +39,7 @@ noinst_HEADERS = \
govirt-private.h \
ovirt-action-rest-call.h \
ovirt-api-private.h \
+ ovirt-cluster-private.h \
ovirt-collection-private.h \
ovirt-host-private.h \
ovirt-proxy-private.h \
@@ -54,6 +56,7 @@ libgovirt_la_SOURCES = \
ovirt-action-rest-call.c \
ovirt-api.c \
ovirt-cdrom.c \
+ ovirt-cluster.c \
ovirt-collection.c \
ovirt-error.c \
ovirt-host.c \
diff --git a/govirt/govirt-private.h b/govirt/govirt-private.h
index b51feb3..d466f7a 100644
--- a/govirt/govirt-private.h
+++ b/govirt/govirt-private.h
@@ -24,6 +24,7 @@

#include <govirt/ovirt-action-rest-call.h>
#include <govirt/ovirt-api-private.h>
+#include <govirt/ovirt-cluster-private.h>
#include <govirt/ovirt-collection-private.h>
#include <govirt/ovirt-enum-types-private.h>
#include <govirt/ovirt-host-private.h>
diff --git a/govirt/govirt.sym b/govirt/govirt.sym
index 6dc8159..56e1d66 100644
--- a/govirt/govirt.sym
+++ b/govirt/govirt.sym
@@ -110,13 +110,19 @@ GOVIRT_0.3.2 {
ovirt_api_search_vms;
ovirt_api_search_vm_pools;

+ ovirt_api_get_clusters;
ovirt_api_get_hosts;

+ ovirt_api_search_clusters;
ovirt_api_search_hosts;
ovirt_api_search_storage_domains;
ovirt_api_search_vms;
ovirt_api_search_vm_pools;

+ ovirt_cluster_get_type;
+ ovirt_cluster_get_hosts;
+ ovirt_cluster_new;
+
ovirt_host_get_type;
ovirt_host_get_vms;
ovirt_host_new;
diff --git a/govirt/ovirt-api.c b/govirt/ovirt-api.c
index fef04ba..14c6c5a 100644
--- a/govirt/ovirt-api.c
+++ b/govirt/ovirt-api.c
@@ -41,6 +41,7 @@


struct _OvirtApiPrivate {
+ OvirtCollection *clusters;
OvirtCollection *hosts;
OvirtCollection *storage_domains;
OvirtCollection *vms;
@@ -74,6 +75,7 @@ static void ovirt_api_dispose(GObject *object)
{
OvirtApi *api = OVIRT_API(object);

+ g_clear_object(&api->priv->clusters);
g_clear_object(&api->priv->hosts);
g_clear_object(&api->priv->storage_domains);
g_clear_object(&api->priv->vms);
@@ -292,3 +294,48 @@ OvirtCollection *ovirt_api_search_hosts(OvirtApi *api, const char *query)
"host",
query);
}
+
+
+/**
+ * ovirt_api_get_clusters:
+ * @api: a #OvirtApi
+ *
+ * This method does not initiate any network activity, the collection
+ * must be fetched with ovirt_collection_fetch() before having up-to-date
+ * content.
+ *
+ * Return value: (transfer none):
+ */
+OvirtCollection *ovirt_api_get_clusters(OvirtApi *api)
+{
+ g_return_val_if_fail(OVIRT_IS_API(api), NULL);
+
+ if (api->priv->clusters == NULL)
+ api->priv->clusters = ovirt_sub_collection_new_from_resource(OVIRT_RESOURCE(api),
+ "clusters",
+ "clusters",
+ OVIRT_TYPE_CLUSTER,
+ "cluster");
+
+ return api->priv->clusters;
+}
+
+
+/**
+ * ovirt_api_search_clusters:
+ * @api: a #OvirtApi
+ * @query: search query
+ *
+ * Return value: (transfer none):
+ */
+OvirtCollection *ovirt_api_search_clusters(OvirtApi *api, const char *query)
+{
+ g_return_val_if_fail(OVIRT_IS_API(api), NULL);
+
+ return ovirt_sub_collection_new_from_resource_search(OVIRT_RESOURCE(api),
+ "clusters/search",
+ "clusters",
+ OVIRT_TYPE_CLUSTER,
+ "cluster",
+ query);
+}
diff --git a/govirt/ovirt-api.h b/govirt/ovirt-api.h
index c46e934..1b60f35 100644
--- a/govirt/ovirt-api.h
+++ b/govirt/ovirt-api.h
@@ -60,6 +60,8 @@ struct _OvirtApiClass
GType ovirt_api_get_type(void);
OvirtApi *ovirt_api_new(void);

+OvirtCollection *ovirt_api_get_clusters(OvirtApi *api);
+OvirtCollection *ovirt_api_search_clusters(OvirtApi *api, const char *query);
OvirtCollection *ovirt_api_get_hosts(OvirtApi *api);
OvirtCollection *ovirt_api_search_hosts(OvirtApi *api, const char *query);
OvirtCollection *ovirt_api_get_storage_domains(OvirtApi *api);
diff --git a/govirt/ovirt-cluster-private.h b/govirt/ovirt-cluster-private.h
new file mode 100644
index 0000000..1a1817d
--- /dev/null
+++ b/govirt/ovirt-cluster-private.h
@@ -0,0 +1,37 @@
+/*
+ * ovirt-cluster-private.h: oVirt cluster resource
+ *
+ * Copyright (C) 2017 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Author: Eduardo Lima (Etrunko) <etrunko@redhat.com>
+ */
+#ifndef __OVIRT_CLUSTER_PRIVATE_H__
+#define __OVIRT_CLUSTER_PRIVATE_H__
+
+#include <ovirt-cluster.h>
+#include <rest/rest-xml-node.h>
+
+G_BEGIN_DECLS
+
+OvirtCluster *ovirt_cluster_new_from_id(const char *id,
+ const char *href);
+OvirtCluster *ovirt_cluster_new_from_xml(RestXmlNode *node,
+ GError **error);
+
+G_END_DECLS
+
+#endif /* __OVIRT_CLUSTER_PRIVATE_H__ */
diff --git a/govirt/ovirt-cluster.c b/govirt/ovirt-cluster.c
new file mode 100644
index 0000000..83b0fa1
--- /dev/null
+++ b/govirt/ovirt-cluster.c
@@ -0,0 +1,215 @@
+/*
+ * ovirt-cluster.c: oVirt cluster handling
+ *
+ * Copyright (C) 2017 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Author: Eduardo Lima (Etrunko) <etrunko@redhat.com>
+ */
+
+#include <config.h>
+#include "ovirt-enum-types.h"
+#include "ovirt-cluster.h"
+#include "govirt-private.h"
+
+#define OVIRT_CLUSTER_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), OVIRT_TYPE_CLUSTER, OvirtClusterPrivate))
+
+struct _OvirtClusterPrivate {
+ gchar *data_center_href;
+ gchar *data_center_id;
+ OvirtCollection *hosts;
+};
+
+G_DEFINE_TYPE(OvirtCluster, ovirt_cluster, OVIRT_TYPE_RESOURCE);
+
+enum {
+ PROP_0,
+ PROP_DATA_CENTER_HREF,
+ PROP_DATA_CENTER_ID,
+};
+
+static void ovirt_cluster_get_property(GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ OvirtCluster *cluster = OVIRT_CLUSTER(object);
+
+ switch (prop_id) {
+ case PROP_DATA_CENTER_HREF:
+ g_value_set_string(value, cluster->priv->data_center_href);
+ break;
+ case PROP_DATA_CENTER_ID:
+ g_value_set_string(value, cluster->priv->data_center_id);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ }
+}
+
+static void ovirt_cluster_set_property(GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ OvirtCluster *cluster = OVIRT_CLUSTER(object);
+
+ switch (prop_id) {
+ case PROP_DATA_CENTER_HREF:
+ g_free(cluster->priv->data_center_href);
+ cluster->priv->data_center_href = g_value_dup_string(value);
+ break;
+ case PROP_DATA_CENTER_ID:
+ g_free(cluster->priv->data_center_id);
+ cluster->priv->data_center_id = g_value_dup_string(value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ }
+}
+
+
+static void
+ovirt_cluster_dispose(GObject *obj)
+{
+ OvirtCluster *cluster = OVIRT_CLUSTER(obj);
+
+ g_clear_pointer(&cluster->priv->data_center_href, g_free);
+ g_clear_pointer(&cluster->priv->data_center_id, g_free);
+ g_clear_object(&cluster->priv->hosts);
+
+ G_OBJECT_CLASS(ovirt_cluster_parent_class)->dispose(obj);
+}
+
+
+static gboolean ovirt_cluster_init_from_xml(OvirtResource *resource,
+ RestXmlNode *node,
+ GError **error)
+{
+ OvirtResourceClass *parent_class;
+ OvirtXmlElement cluster_elements[] = {
+ { .prop_name = "data-center-href",
+ .type = G_TYPE_STRING,
+ .xml_path = "data_center",
+ .xml_attr = "href",
+ },
+ { .prop_name = "data-center-id",
+ .type = G_TYPE_STRING,
+ .xml_path = "data_center",
+ .xml_attr = "id",
+ },
+ { NULL , },
+ };
+
+ if (!ovirt_rest_xml_node_parse(node, G_OBJECT(resource), cluster_elements))
+ return FALSE;
+
+ parent_class = OVIRT_RESOURCE_CLASS(ovirt_cluster_parent_class);
+ return parent_class->init_from_xml(resource, node, error);
+}
+
+
+static void ovirt_cluster_class_init(OvirtClusterClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS(klass);
+ OvirtResourceClass *resource_class = OVIRT_RESOURCE_CLASS(klass);
+ GParamSpec *param_spec;
+
+ g_type_class_add_private(klass, sizeof(OvirtClusterPrivate));
+
+ resource_class->init_from_xml = ovirt_cluster_init_from_xml;
+ object_class->dispose = ovirt_cluster_dispose;
+ object_class->get_property = ovirt_cluster_get_property;
+ object_class->set_property = ovirt_cluster_set_property;
+
+ param_spec = g_param_spec_string("data-center-href",
+ "Data Center href",
+ "Data Center href for the Cluster",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property(object_class,
+ PROP_DATA_CENTER_HREF,
+ param_spec);
+
+ param_spec = g_param_spec_string("data-center-id",
+ "Data Center Id",
+ "Data Center Id for the Cluster",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property(object_class,
+ PROP_DATA_CENTER_ID,
+ param_spec);
+}
+
+static void ovirt_cluster_init(OvirtCluster *cluster)
+{
+ cluster->priv = OVIRT_CLUSTER_GET_PRIVATE(cluster);
+}
+
+G_GNUC_INTERNAL
+OvirtCluster *ovirt_cluster_new_from_id(const char *id,
+ const char *href)
+{
+ OvirtResource *cluster = ovirt_resource_new_from_id(OVIRT_TYPE_CLUSTER, id, href);
+ return OVIRT_CLUSTER(cluster);
+}
+
+G_GNUC_INTERNAL
+OvirtCluster *ovirt_cluster_new_from_xml(RestXmlNode *node,
+ GError **error)
+{
+ OvirtResource *cluster = ovirt_resource_new_from_xml(OVIRT_TYPE_CLUSTER, node, error);
+ return OVIRT_CLUSTER(cluster);
+}
+
+OvirtCluster *ovirt_cluster_new(void)
+{
+ OvirtResource *cluster = ovirt_resource_new(OVIRT_TYPE_CLUSTER);
+ return OVIRT_CLUSTER(cluster);
+}
+
+/**
+ * ovirt_cluster_get_hosts:
+ * @cluster: a #OvirtCluster
+ *
+ * Gets a #OvirtCollection representing the list of remote hosts from a
+ * cluster object. This method does not initiate any network
+ * activity, the remote host list must be then be fetched using
+ * ovirt_collection_fetch() or ovirt_collection_fetch_async().
+ *
+ * Return value: (transfer none): a #OvirtCollection representing the list
+ * of hosts associated with @cluster.
+ */
+OvirtCollection *ovirt_cluster_get_hosts(OvirtCluster *cluster)
+{
+ g_return_val_if_fail(OVIRT_IS_CLUSTER(cluster), NULL);
+
+ if (cluster->priv->hosts == NULL) {
+ OvirtCollection *collection;
+ collection = ovirt_sub_collection_new_from_resource(OVIRT_RESOURCE(cluster),
+ "hosts",
+ "hosts",
+ OVIRT_TYPE_HOST,
+ "host");
+ cluster->priv->hosts = collection;
+ }
+
+ return cluster->priv->hosts;
+}
+
diff --git a/govirt/ovirt-cluster.h b/govirt/ovirt-cluster.h
new file mode 100644
index 0000000..9505e8c
--- /dev/null
+++ b/govirt/ovirt-cluster.h
@@ -0,0 +1,66 @@
+/*
+ * ovirt-cluster.h: oVirt cluster resource
+ *
+ * Copyright (C) 2017 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Author: Eduardo Lima (Etrunko) <etrunko@redhat.com>
+ */
+#ifndef __OVIRT_CLUSTER_H__
+#define __OVIRT_CLUSTER_H__
+
+#include <gio/gio.h>
+#include <glib-object.h>
+#include <govirt/ovirt-collection.h>
+#include <govirt/ovirt-resource.h>
+#include <govirt/ovirt-types.h>
+
+G_BEGIN_DECLS
+
+#define OVIRT_TYPE_CLUSTER (ovirt_cluster_get_type ())
+#define OVIRT_CLUSTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), OVIRT_TYPE_CLUSTER, OvirtCluster))
+#define OVIRT_CLUSTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), OVIRT_TYPE_CLUSTER, OvirtClusterClass))
+#define OVIRT_IS_CLUSTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OVIRT_TYPE_CLUSTER))
+#define OVIRT_IS_CLUSTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), OVIRT_TYPE_CLUSTER))
+#define OVIRT_CLUSTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), OVIRT_TYPE_CLUSTER, OvirtClusterClass))
+
+typedef struct _OvirtClusterPrivate OvirtClusterPrivate;
+typedef struct _OvirtClusterClass OvirtClusterClass;
+
+struct _OvirtCluster
+{
+ OvirtResource parent;
+
+ OvirtClusterPrivate *priv;
+
+ /* Do not add fields to this struct */
+};
+
+struct _OvirtClusterClass
+{
+ OvirtResourceClass parent_class;
+
+ gpointer padding[20];
+};
+
+GType ovirt_cluster_get_type(void);
+
+OvirtCluster *ovirt_cluster_new(void);
+OvirtCollection *ovirt_cluster_get_hosts(OvirtCluster *cluster);
+
+G_END_DECLS
+
+#endif /* __OVIRT_CLUSTER_H__ */
diff --git a/govirt/ovirt-types.h b/govirt/ovirt-types.h
index 42fc004..e2f196e 100644
--- a/govirt/ovirt-types.h
+++ b/govirt/ovirt-types.h
@@ -27,6 +27,7 @@ G_BEGIN_DECLS

typedef struct _OvirtApi OvirtApi;
typedef struct _OvirtCdrom OvirtCdrom;
+typedef struct _OvirtCluster OvirtCluster;
typedef struct _OvirtCollection OvirtCollection;
typedef struct _OvirtHost OvirtHost;
typedef struct _OvirtProxy OvirtProxy;

452
SOURCES/0021-Initial-support-for-data-centers.patch

@ -0,0 +1,452 @@ @@ -0,0 +1,452 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: "Eduardo Lima (Etrunko)" <etrunko@redhat.com>
Date: Tue, 11 Apr 2017 21:53:26 -0300
Subject: [PATCH] Initial support for data centers

For this higher level object, the list of clusters and storage domains
associated with it are stored.

Signed-off-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
---
govirt/Makefile.am | 3 +
govirt/govirt-private.h | 1 +
govirt/govirt.sym | 7 ++
govirt/ovirt-api.c | 47 ++++++++++
govirt/ovirt-api.h | 2 +
govirt/ovirt-data-center-private.h | 37 ++++++++
govirt/ovirt-data-center.c | 144 +++++++++++++++++++++++++++++
govirt/ovirt-data-center.h | 67 ++++++++++++++
govirt/ovirt-types.h | 1 +
9 files changed, 309 insertions(+)
create mode 100644 govirt/ovirt-data-center-private.h
create mode 100644 govirt/ovirt-data-center.c
create mode 100644 govirt/ovirt-data-center.h

diff --git a/govirt/Makefile.am b/govirt/Makefile.am
index cf6b858..9bf0eba 100644
--- a/govirt/Makefile.am
+++ b/govirt/Makefile.am
@@ -21,6 +21,7 @@ libgovirt_la_HEADERS = \
ovirt-cdrom.h \
ovirt-cluster.h \
ovirt-collection.h \
+ ovirt-data-center.h \
ovirt-error.h \
ovirt-host.h \
ovirt-options.h \
@@ -41,6 +42,7 @@ noinst_HEADERS = \
ovirt-api-private.h \
ovirt-cluster-private.h \
ovirt-collection-private.h \
+ ovirt-data-center-private.h \
ovirt-host-private.h \
ovirt-proxy-private.h \
ovirt-resource-private.h \
@@ -58,6 +60,7 @@ libgovirt_la_SOURCES = \
ovirt-cdrom.c \
ovirt-cluster.c \
ovirt-collection.c \
+ ovirt-data-center.c \
ovirt-error.c \
ovirt-host.c \
ovirt-options.c \
diff --git a/govirt/govirt-private.h b/govirt/govirt-private.h
index d466f7a..cd98b5b 100644
--- a/govirt/govirt-private.h
+++ b/govirt/govirt-private.h
@@ -26,6 +26,7 @@
#include <govirt/ovirt-api-private.h>
#include <govirt/ovirt-cluster-private.h>
#include <govirt/ovirt-collection-private.h>
+#include <govirt/ovirt-data-center-private.h>
#include <govirt/ovirt-enum-types-private.h>
#include <govirt/ovirt-host-private.h>
#include <govirt/ovirt-proxy-private.h>
diff --git a/govirt/govirt.sym b/govirt/govirt.sym
index 56e1d66..b22af76 100644
--- a/govirt/govirt.sym
+++ b/govirt/govirt.sym
@@ -111,9 +111,11 @@ GOVIRT_0.3.2 {
ovirt_api_search_vm_pools;

ovirt_api_get_clusters;
+ ovirt_api_get_data_centers;
ovirt_api_get_hosts;

ovirt_api_search_clusters;
+ ovirt_api_search_data_centers;
ovirt_api_search_hosts;
ovirt_api_search_storage_domains;
ovirt_api_search_vms;
@@ -123,6 +125,11 @@ GOVIRT_0.3.2 {
ovirt_cluster_get_hosts;
ovirt_cluster_new;

+ ovirt_data_center_get_clusters;
+ ovirt_data_center_get_storage_domains;
+ ovirt_data_center_get_type;
+ ovirt_data_center_new;
+
ovirt_host_get_type;
ovirt_host_get_vms;
ovirt_host_new;
diff --git a/govirt/ovirt-api.c b/govirt/ovirt-api.c
index 14c6c5a..d78ba7e 100644
--- a/govirt/ovirt-api.c
+++ b/govirt/ovirt-api.c
@@ -42,6 +42,7 @@

struct _OvirtApiPrivate {
OvirtCollection *clusters;
+ OvirtCollection *data_centers;
OvirtCollection *hosts;
OvirtCollection *storage_domains;
OvirtCollection *vms;
@@ -76,6 +77,7 @@ static void ovirt_api_dispose(GObject *object)
OvirtApi *api = OVIRT_API(object);

g_clear_object(&api->priv->clusters);
+ g_clear_object(&api->priv->data_centers);
g_clear_object(&api->priv->hosts);
g_clear_object(&api->priv->storage_domains);
g_clear_object(&api->priv->vms);
@@ -339,3 +341,48 @@ OvirtCollection *ovirt_api_search_clusters(OvirtApi *api, const char *query)
"cluster",
query);
}
+
+
+/**
+ * ovirt_api_get_data_centers:
+ * @api: a #OvirtApi
+ *
+ * This method does not initiate any network activity, the collection
+ * must be fetched with ovirt_collection_fetch() before having up-to-date
+ * content.
+ *
+ * Return value: (transfer none):
+ */
+OvirtCollection *ovirt_api_get_data_centers(OvirtApi *api)
+{
+ g_return_val_if_fail(OVIRT_IS_API(api), NULL);
+
+ if (api->priv->data_centers == NULL)
+ api->priv->data_centers = ovirt_sub_collection_new_from_resource(OVIRT_RESOURCE(api),
+ "datacenters",
+ "data_centers",
+ OVIRT_TYPE_DATA_CENTER,
+ "data_center");
+
+ return api->priv->data_centers;
+}
+
+
+/**
+ * ovirt_api_search_data_centers:
+ * @api: a #OvirtApi
+ * @query: search query
+ *
+ * Return value: (transfer none):
+ */
+OvirtCollection *ovirt_api_search_data_centers(OvirtApi *api, const char *query)
+{
+ g_return_val_if_fail(OVIRT_IS_API(api), NULL);
+
+ return ovirt_sub_collection_new_from_resource_search(OVIRT_RESOURCE(api),
+ "datacenters/search",
+ "data_centers",
+ OVIRT_TYPE_DATA_CENTER,
+ "data_center",
+ query);
+}
diff --git a/govirt/ovirt-api.h b/govirt/ovirt-api.h
index 1b60f35..1448296 100644
--- a/govirt/ovirt-api.h
+++ b/govirt/ovirt-api.h
@@ -62,6 +62,8 @@ OvirtApi *ovirt_api_new(void);

OvirtCollection *ovirt_api_get_clusters(OvirtApi *api);
OvirtCollection *ovirt_api_search_clusters(OvirtApi *api, const char *query);
+OvirtCollection *ovirt_api_get_data_centers(OvirtApi *api);
+OvirtCollection *ovirt_api_search_data_centers(OvirtApi *api, const char *query);
OvirtCollection *ovirt_api_get_hosts(OvirtApi *api);
OvirtCollection *ovirt_api_search_hosts(OvirtApi *api, const char *query);
OvirtCollection *ovirt_api_get_storage_domains(OvirtApi *api);
diff --git a/govirt/ovirt-data-center-private.h b/govirt/ovirt-data-center-private.h
new file mode 100644
index 0000000..5839755
--- /dev/null
+++ b/govirt/ovirt-data-center-private.h
@@ -0,0 +1,37 @@
+/*
+ * ovirt-data_center-private.h: oVirt data center resource
+ *
+ * Copyright (C) 2017 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Author: Eduardo Lima (Etrunko) <etrunko@redhat.com>
+ */
+#ifndef __OVIRT_DATA_CENTER_PRIVATE_H__
+#define __OVIRT_DATA_CENTER_PRIVATE_H__
+
+#include <ovirt-data-center.h>
+#include <rest/rest-xml-node.h>
+
+G_BEGIN_DECLS
+
+OvirtDataCenter *ovirt_data_center_new_from_id(const char *id,
+ const char *href);
+OvirtDataCenter *ovirt_data_center_new_from_xml(RestXmlNode *node,
+ GError **error);
+
+G_END_DECLS
+
+#endif /* __OVIRT_DATA_CENTER_PRIVATE_H__ */
diff --git a/govirt/ovirt-data-center.c b/govirt/ovirt-data-center.c
new file mode 100644
index 0000000..577a31f
--- /dev/null
+++ b/govirt/ovirt-data-center.c
@@ -0,0 +1,144 @@
+/*
+ * ovirt-data_center.c: oVirt data center handling
+ *
+ * Copyright (C) 2017 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Author: Eduardo Lima (Etrunko) <etrunko@redhat.com>
+ */
+
+#include <config.h>
+#include "ovirt-enum-types.h"
+#include "ovirt-data-center.h"
+#include "govirt-private.h"
+
+#define OVIRT_DATA_CENTER_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), OVIRT_TYPE_DATA_CENTER, OvirtDataCenterPrivate))
+
+struct _OvirtDataCenterPrivate {
+ OvirtCollection *clusters;
+ OvirtCollection *storage_domains;
+};
+
+G_DEFINE_TYPE(OvirtDataCenter, ovirt_data_center, OVIRT_TYPE_RESOURCE);
+
+static void
+ovirt_data_center_dispose(GObject *obj)
+{
+ OvirtDataCenter *data_center = OVIRT_DATA_CENTER(obj);
+
+ g_clear_object(&data_center->priv->clusters);
+ g_clear_object(&data_center->priv->storage_domains);
+
+ G_OBJECT_CLASS(ovirt_data_center_parent_class)->dispose(obj);
+}
+
+static void ovirt_data_center_class_init(OvirtDataCenterClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS(klass);
+
+ g_type_class_add_private(klass, sizeof(OvirtDataCenterPrivate));
+
+ object_class->dispose = ovirt_data_center_dispose;
+}
+
+
+static void ovirt_data_center_init(OvirtDataCenter *data_center)
+{
+ data_center->priv = OVIRT_DATA_CENTER_GET_PRIVATE(data_center);
+}
+
+G_GNUC_INTERNAL
+OvirtDataCenter *ovirt_data_center_new_from_id(const char *id,
+ const char *href)
+{
+ OvirtResource *data_center = ovirt_resource_new_from_id(OVIRT_TYPE_DATA_CENTER, id, href);
+ return OVIRT_DATA_CENTER(data_center);
+}
+
+G_GNUC_INTERNAL
+OvirtDataCenter *ovirt_data_center_new_from_xml(RestXmlNode *node,
+ GError **error)
+{
+ OvirtResource *data_center = ovirt_resource_new_from_xml(OVIRT_TYPE_DATA_CENTER, node, error);
+ return OVIRT_DATA_CENTER(data_center);
+}
+
+OvirtDataCenter *ovirt_data_center_new(void)
+{
+ OvirtResource *data_center = ovirt_resource_new(OVIRT_TYPE_DATA_CENTER);
+ return OVIRT_DATA_CENTER(data_center);
+}
+
+
+/**
+ * ovirt_data_center_get_clusters:
+ * @data_center: a #OvirtDataCenter
+ *
+ * Gets a #OvirtCollection representing the list of remote clusters from a
+ * data center object. This method does not initiate any network
+ * activity, the remote cluster list must be then be fetched using
+ * ovirt_collection_fetch() or ovirt_collection_fetch_async().
+ *
+ * Return value: (transfer none): a #OvirtCollection representing the list
+ * of clusters associated with @data_center.
+ */
+OvirtCollection *ovirt_data_center_get_clusters(OvirtDataCenter *data_center)
+{
+ g_return_val_if_fail(OVIRT_IS_DATA_CENTER(data_center), NULL);
+
+ if (data_center->priv->clusters == NULL) {
+ OvirtCollection *collection;
+ collection = ovirt_sub_collection_new_from_resource(OVIRT_RESOURCE(data_center),
+ "clusters",
+ "clusters",
+ OVIRT_TYPE_CLUSTER,
+ "cluster");
+ data_center->priv->clusters = collection;
+ }
+
+ return data_center->priv->clusters;
+}
+
+
+/**
+ * ovirt_data_center_get_storage_domains:
+ * @data_center: a #OvirtDataCenter
+ *
+ * Gets a #OvirtCollection representing the list of remote storage domains from a
+ * data center object. This method does not initiate any network
+ * activity, the remote storage domain list must be then be fetched using
+ * ovirt_collection_fetch() or ovirt_collection_fetch_async().
+ *
+ * Return value: (transfer none): a #OvirtCollection representing the list
+ * of storage_domains associated with @data_center.
+ */
+OvirtCollection *ovirt_data_center_get_storage_domains(OvirtDataCenter *data_center)
+{
+ g_return_val_if_fail(OVIRT_IS_DATA_CENTER(data_center), NULL);
+
+ if (data_center->priv->storage_domains == NULL) {
+ OvirtCollection *collection;
+ collection = ovirt_sub_collection_new_from_resource(OVIRT_RESOURCE(data_center),
+ "storagedomains",
+ "storage_domains",
+ OVIRT_TYPE_STORAGE_DOMAIN,
+ "storage_domain");
+ data_center->priv->storage_domains = collection;
+ }
+
+ return data_center->priv->storage_domains;
+}
diff --git a/govirt/ovirt-data-center.h b/govirt/ovirt-data-center.h
new file mode 100644
index 0000000..1bad06f
--- /dev/null
+++ b/govirt/ovirt-data-center.h
@@ -0,0 +1,67 @@
+/*
+ * ovirt-data_center.h: oVirt data center resource
+ *
+ * Copyright (C) 2017 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Author: Eduardo Lima (Etrunko) <etrunko@redhat.com>
+ */
+#ifndef __OVIRT_DATA_CENTER_H__
+#define __OVIRT_DATA_CENTER_H__
+
+#include <gio/gio.h>
+#include <glib-object.h>
+#include <govirt/ovirt-collection.h>
+#include <govirt/ovirt-resource.h>
+#include <govirt/ovirt-types.h>
+
+G_BEGIN_DECLS
+
+#define OVIRT_TYPE_DATA_CENTER (ovirt_data_center_get_type ())
+#define OVIRT_DATA_CENTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), OVIRT_TYPE_DATA_CENTER, OvirtDataCenter))
+#define OVIRT_DATA_CENTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), OVIRT_TYPE_DATA_CENTER, OvirtDataCenterClass))
+#define OVIRT_IS_DATA_CENTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OVIRT_TYPE_DATA_CENTER))
+#define OVIRT_IS_DATA_CENTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), OVIRT_TYPE_DATA_CENTER))
+#define OVIRT_DATA_CENTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), OVIRT_TYPE_DATA_CENTER, OvirtDataCenterClass))
+
+typedef struct _OvirtDataCenterPrivate OvirtDataCenterPrivate;
+typedef struct _OvirtDataCenterClass OvirtDataCenterClass;
+
+struct _OvirtDataCenter
+{
+ OvirtResource parent;
+
+ OvirtDataCenterPrivate *priv;
+
+ /* Do not add fields to this struct */
+};
+
+struct _OvirtDataCenterClass
+{
+ OvirtResourceClass parent_class;
+
+ gpointer padding[20];
+};
+
+GType ovirt_data_center_get_type(void);
+
+OvirtDataCenter *ovirt_data_center_new(void);
+OvirtCollection *ovirt_data_center_get_clusters(OvirtDataCenter *data_center);
+OvirtCollection *ovirt_data_center_get_storage_domains(OvirtDataCenter *data_center);
+
+G_END_DECLS
+
+#endif /* __OVIRT_DATA_CENTER_H__ */
diff --git a/govirt/ovirt-types.h b/govirt/ovirt-types.h
index e2f196e..eb85fd6 100644
--- a/govirt/ovirt-types.h
+++ b/govirt/ovirt-types.h
@@ -29,6 +29,7 @@ typedef struct _OvirtApi OvirtApi;
typedef struct _OvirtCdrom OvirtCdrom;
typedef struct _OvirtCluster OvirtCluster;
typedef struct _OvirtCollection OvirtCollection;
+typedef struct _OvirtDataCenter OvirtDataCenter;
typedef struct _OvirtHost OvirtHost;
typedef struct _OvirtProxy OvirtProxy;
typedef struct _OvirtStorageDomain OvirtStorageDomain;

195
SOURCES/0022-vm-Introduce-ovirt_vm_get_host.patch

@ -0,0 +1,195 @@ @@ -0,0 +1,195 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: "Eduardo Lima (Etrunko)" <etrunko@redhat.com>
Date: Thu, 13 Jul 2017 18:02:49 -0300
Subject: [PATCH] vm: Introduce ovirt_vm_get_host()

With initial support for hosts implemented, this new function can be
used to retrieve the host the virtual machine belongs to.

Signed-off-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
---
govirt/govirt.sym | 2 ++
govirt/ovirt-vm.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++-
govirt/ovirt-vm.h | 1 +
3 files changed, 94 insertions(+), 1 deletion(-)

diff --git a/govirt/govirt.sym b/govirt/govirt.sym
index b22af76..039c88b 100644
--- a/govirt/govirt.sym
+++ b/govirt/govirt.sym
@@ -133,6 +133,8 @@ GOVIRT_0.3.2 {
ovirt_host_get_type;
ovirt_host_get_vms;
ovirt_host_new;
+
+ ovirt_vm_get_host;
} GOVIRT_0.3.1;

GOVIRT_0.3.4 {
diff --git a/govirt/ovirt-vm.c b/govirt/ovirt-vm.c
index 806b5f3..6016c77 100644
--- a/govirt/ovirt-vm.c
+++ b/govirt/ovirt-vm.c
@@ -42,6 +42,8 @@ struct _OvirtVmPrivate {

OvirtVmState state;
OvirtVmDisplay *display;
+ gchar *host_href;
+ gchar *host_id;
} ;
G_DEFINE_TYPE(OvirtVm, ovirt_vm, OVIRT_TYPE_RESOURCE);

@@ -56,9 +58,28 @@ enum OvirtResponseStatus {
enum {
PROP_0,
PROP_STATE,
- PROP_DISPLAY
+ PROP_DISPLAY,
+ PROP_HOST_HREF,
+ PROP_HOST_ID,
};

+static char *ensure_href_from_id(const char *id,
+ const char *path)
+{
+ if (id == NULL)
+ return NULL;
+
+ return g_strdup_printf("%s/%s", path, id);
+}
+
+static const char *get_host_href(OvirtVm *vm)
+{
+ if (vm->priv->host_href == NULL)
+ vm->priv->host_href = ensure_href_from_id(vm->priv->host_id, "/ovirt-engine/api/hosts");
+
+ return vm->priv->host_href;
+}
+
static void ovirt_vm_get_property(GObject *object,
guint prop_id,
GValue *value,
@@ -73,6 +94,12 @@ static void ovirt_vm_get_property(GObject *object,
case PROP_DISPLAY:
g_value_set_object(value, vm->priv->display);
break;
+ case PROP_HOST_HREF:
+ g_value_set_string(value, get_host_href(vm));
+ break;
+ case PROP_HOST_ID:
+ g_value_set_string(value, vm->priv->host_id);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
}
@@ -94,6 +121,14 @@ static void ovirt_vm_set_property(GObject *object,
g_object_unref(vm->priv->display);
vm->priv->display = g_value_dup_object(value);
break;
+ case PROP_HOST_HREF:
+ g_free(vm->priv->host_href);
+ vm->priv->host_href = g_value_dup_string(value);
+ break;
+ case PROP_HOST_ID:
+ g_free(vm->priv->host_id);
+ vm->priv->host_id = g_value_dup_string(value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
}
@@ -106,6 +141,8 @@ static void ovirt_vm_dispose(GObject *object)

g_clear_object(&vm->priv->cdroms);
g_clear_object(&vm->priv->display);
+ g_clear_pointer(&vm->priv->host_href, g_free);
+ g_clear_pointer(&vm->priv->host_id, g_free);

G_OBJECT_CLASS(ovirt_vm_parent_class)->dispose(object);
}
@@ -117,11 +154,28 @@ static gboolean ovirt_vm_init_from_xml(OvirtResource *resource,
{
gboolean parsed_ok;
OvirtResourceClass *parent_class;
+ OvirtXmlElement vm_elements[] = {
+ { .prop_name = "host-href",
+ .type = G_TYPE_STRING,
+ .xml_path = "host",
+ .xml_attr = "href",
+ },
+ { .prop_name = "host-id",
+ .type = G_TYPE_STRING,
+ .xml_path = "host",
+ .xml_attr = "id",
+ },
+ { NULL, },
+ };

parsed_ok = ovirt_vm_refresh_from_xml(OVIRT_VM(resource), node);
if (!parsed_ok) {
return FALSE;
}
+
+ if (!ovirt_rest_xml_node_parse(node, G_OBJECT(resource), vm_elements))
+ return FALSE;
+
parent_class = OVIRT_RESOURCE_CLASS(ovirt_vm_parent_class);

return parent_class->init_from_xml(resource, node, error);
@@ -156,6 +210,22 @@ static void ovirt_vm_class_init(OvirtVmClass *klass)
OVIRT_TYPE_VM_DISPLAY,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property(object_class,
+ PROP_HOST_HREF,
+ g_param_spec_string("host-href",
+ "Host href",
+ "Host href for the Virtual Machine",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property(object_class,
+ PROP_HOST_ID,
+ g_param_spec_string("host-id",
+ "Host Id",
+ "Host Id for the Virtual Machine",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
}

static void ovirt_vm_init(G_GNUC_UNUSED OvirtVm *vm)
@@ -342,3 +412,23 @@ OvirtCollection *ovirt_vm_get_cdroms(OvirtVm *vm)

return vm->priv->cdroms;
}
+
+
+/**
+ * ovirt_vm_get_host:
+ * @vm: a #OvirtVm
+ *
+ * Gets a #OvirtHost representing the host the virtual machine belongs to.
+ * This method does not initiate any network activity, the remote host must be
+ * then be fetched using ovirt_resource_refresh() or
+ * ovirt_resource_refresh_async().
+ *
+ * Return value: (transfer full): a #OvirtHost representing host the @vm
+ * belongs to.
+ */
+OvirtHost *ovirt_vm_get_host(OvirtVm *vm)
+{
+ g_return_val_if_fail(OVIRT_IS_VM(vm), NULL);
+ g_return_val_if_fail(vm->priv->host_id != NULL, NULL);
+ return ovirt_host_new_from_id(vm->priv->host_id, get_host_href(vm));
+}
diff --git a/govirt/ovirt-vm.h b/govirt/ovirt-vm.h
index 1e6c7ad..e230ebb 100644
--- a/govirt/ovirt-vm.h
+++ b/govirt/ovirt-vm.h
@@ -120,6 +120,7 @@ gboolean ovirt_vm_refresh_finish(OvirtVm *vm,
GError **err);

OvirtCollection *ovirt_vm_get_cdroms(OvirtVm *vm);
+OvirtHost *ovirt_vm_get_host(OvirtVm *vm);

G_END_DECLS

176
SOURCES/0023-vm-Introduce-ovirt_vm_get_cluster.patch

@ -0,0 +1,176 @@ @@ -0,0 +1,176 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: "Eduardo Lima (Etrunko)" <etrunko@redhat.com>
Date: Thu, 13 Jul 2017 18:03:11 -0300
Subject: [PATCH] vm: Introduce ovirt_vm_get_cluster()

Similar to previous commit, this new function can be used to retrieve
the cluster the virtual machine belongs to.

Signed-off-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
---
govirt/govirt.sym | 1 +
govirt/ovirt-vm.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++
govirt/ovirt-vm.h | 1 +
3 files changed, 76 insertions(+)

diff --git a/govirt/govirt.sym b/govirt/govirt.sym
index 039c88b..bbfbd79 100644
--- a/govirt/govirt.sym
+++ b/govirt/govirt.sym
@@ -135,6 +135,7 @@ GOVIRT_0.3.2 {
ovirt_host_new;

ovirt_vm_get_host;
+ ovirt_vm_get_cluster;
} GOVIRT_0.3.1;

GOVIRT_0.3.4 {
diff --git a/govirt/ovirt-vm.c b/govirt/ovirt-vm.c
index 6016c77..70b6f3a 100644
--- a/govirt/ovirt-vm.c
+++ b/govirt/ovirt-vm.c
@@ -44,6 +44,8 @@ struct _OvirtVmPrivate {
OvirtVmDisplay *display;
gchar *host_href;
gchar *host_id;
+ gchar *cluster_href;
+ gchar *cluster_id;
} ;
G_DEFINE_TYPE(OvirtVm, ovirt_vm, OVIRT_TYPE_RESOURCE);

@@ -61,6 +63,8 @@ enum {
PROP_DISPLAY,
PROP_HOST_HREF,
PROP_HOST_ID,
+ PROP_CLUSTER_HREF,
+ PROP_CLUSTER_ID,
};

static char *ensure_href_from_id(const char *id,
@@ -80,6 +84,14 @@ static const char *get_host_href(OvirtVm *vm)
return vm->priv->host_href;
}

+static const char *get_cluster_href(OvirtVm *vm)
+{
+ if (vm->priv->cluster_href == NULL)
+ vm->priv->cluster_href = ensure_href_from_id(vm->priv->cluster_id, "/ovirt-engine/api/clusters");
+
+ return vm->priv->cluster_href;
+}
+
static void ovirt_vm_get_property(GObject *object,
guint prop_id,
GValue *value,
@@ -100,6 +112,12 @@ static void ovirt_vm_get_property(GObject *object,
case PROP_HOST_ID:
g_value_set_string(value, vm->priv->host_id);
break;
+ case PROP_CLUSTER_HREF:
+ g_value_set_string(value, get_cluster_href(vm));
+ break;
+ case PROP_CLUSTER_ID:
+ g_value_set_string(value, vm->priv->cluster_id);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
}
@@ -129,6 +147,14 @@ static void ovirt_vm_set_property(GObject *object,
g_free(vm->priv->host_id);
vm->priv->host_id = g_value_dup_string(value);
break;
+ case PROP_CLUSTER_HREF:
+ g_free(vm->priv->cluster_href);
+ vm->priv->cluster_href = g_value_dup_string(value);
+ break;
+ case PROP_CLUSTER_ID:
+ g_free(vm->priv->cluster_id);
+ vm->priv->cluster_id = g_value_dup_string(value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
}
@@ -143,6 +169,8 @@ static void ovirt_vm_dispose(GObject *object)
g_clear_object(&vm->priv->display);
g_clear_pointer(&vm->priv->host_href, g_free);
g_clear_pointer(&vm->priv->host_id, g_free);
+ g_clear_pointer(&vm->priv->cluster_href, g_free);
+ g_clear_pointer(&vm->priv->cluster_id, g_free);

G_OBJECT_CLASS(ovirt_vm_parent_class)->dispose(object);
}
@@ -165,6 +193,16 @@ static gboolean ovirt_vm_init_from_xml(OvirtResource *resource,
.xml_path = "host",
.xml_attr = "id",
},
+ { .prop_name = "cluster-href",
+ .type = G_TYPE_STRING,
+ .xml_path = "cluster",
+ .xml_attr = "href",
+ },
+ { .prop_name = "cluster-id",
+ .type = G_TYPE_STRING,
+ .xml_path = "cluster",
+ .xml_attr = "id",
+ },
{ NULL, },
};

@@ -226,6 +264,22 @@ static void ovirt_vm_class_init(OvirtVmClass *klass)
NULL,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property(object_class,
+ PROP_CLUSTER_HREF,
+ g_param_spec_string("cluster-href",
+ "Cluster href",
+ "Cluster href for the Virtual Machine",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property(object_class,
+ PROP_CLUSTER_ID,
+ g_param_spec_string("cluster-id",
+ "Cluster Id",
+ "Cluster Id for the Virtual Machine",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
}

static void ovirt_vm_init(G_GNUC_UNUSED OvirtVm *vm)
@@ -432,3 +486,23 @@ OvirtHost *ovirt_vm_get_host(OvirtVm *vm)
g_return_val_if_fail(vm->priv->host_id != NULL, NULL);
return ovirt_host_new_from_id(vm->priv->host_id, get_host_href(vm));
}
+
+
+/**
+ * ovirt_vm_get_cluster:
+ * @vm: a #OvirtVm
+ *
+ * Gets a #OvirtCluster representing the cluster the virtual machine belongs
+ * to. This method does not initiate any network activity, the remote host must
+ * be then be fetched using ovirt_resource_refresh() or
+ * ovirt_resource_refresh_async().
+ *
+ * Return value: (transfer full): a #OvirtCluster representing cluster the @vm
+ * belongs to.
+ */
+OvirtCluster *ovirt_vm_get_cluster(OvirtVm *vm)
+{
+ g_return_val_if_fail(OVIRT_IS_VM(vm), NULL);
+ g_return_val_if_fail(vm->priv->cluster_id != NULL, NULL);
+ return ovirt_cluster_new_from_id(vm->priv->cluster_id, get_cluster_href(vm));
+}
diff --git a/govirt/ovirt-vm.h b/govirt/ovirt-vm.h
index e230ebb..bef4289 100644
--- a/govirt/ovirt-vm.h
+++ b/govirt/ovirt-vm.h
@@ -121,6 +121,7 @@ gboolean ovirt_vm_refresh_finish(OvirtVm *vm,

OvirtCollection *ovirt_vm_get_cdroms(OvirtVm *vm);
OvirtHost *ovirt_vm_get_host(OvirtVm *vm);
+OvirtCluster *ovirt_vm_get_cluster(OvirtVm *vm);

G_END_DECLS

95
SOURCES/0024-host-Introduce-ovirt_host_get_cluster.patch

@ -0,0 +1,95 @@ @@ -0,0 +1,95 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: "Eduardo Lima (Etrunko)" <etrunko@redhat.com>
Date: Thu, 13 Jul 2017 17:44:13 -0300
Subject: [PATCH] host: Introduce ovirt_host_get_cluster()

Following the same principle as previous commits, this functions can be
used to retrieve the cluster that includes this host.

Signed-off-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
---
govirt/govirt.sym | 1 +
govirt/ovirt-host.c | 35 ++++++++++++++++++++++++++++++++++-
govirt/ovirt-host.h | 1 +
3 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/govirt/govirt.sym b/govirt/govirt.sym
index bbfbd79..243ce0b 100644
--- a/govirt/govirt.sym
+++ b/govirt/govirt.sym
@@ -130,6 +130,7 @@ GOVIRT_0.3.2 {
ovirt_data_center_get_type;
ovirt_data_center_new;

+ ovirt_host_get_cluster;
ovirt_host_get_type;
ovirt_host_get_vms;
ovirt_host_new;
diff --git a/govirt/ovirt-host.c b/govirt/ovirt-host.c
index 2df2a64..191b360 100644
--- a/govirt/ovirt-host.c
+++ b/govirt/ovirt-host.c
@@ -42,6 +42,19 @@ enum {
PROP_CLUSTER_ID,
};

+
+static const char *get_cluster_href(OvirtHost *host)
+{
+ if (host->priv->cluster_href == NULL &&
+ host->priv->cluster_id != NULL) {
+ host->priv->cluster_href = g_strdup_printf("%s/%s",
+ "/ovirt-engine/api/clusters",
+ host->priv->cluster_id);
+ }
+
+ return host->priv->cluster_href;
+}
+
static void ovirt_host_get_property(GObject *object,
guint prop_id,
GValue *value,
@@ -51,7 +64,7 @@ static void ovirt_host_get_property(GObject *object,

switch (prop_id) {
case PROP_CLUSTER_HREF:
- g_value_set_string(value, host->priv->cluster_href);
+ g_value_set_string(value, get_cluster_href(host));
break;
case PROP_CLUSTER_ID:
g_value_set_string(value, host->priv->cluster_id);
@@ -212,3 +225,23 @@ OvirtCollection *ovirt_host_get_vms(OvirtHost *host)

return host->priv->vms;
}
+
+
+/**
+ * ovirt_host_get_cluster:
+ * @host: a #OvirtHost
+ *
+ * Gets a #OvirtCluster representing the cluster the host belongs
+ * to. This method does not initiate any network activity, the remote host must
+ * be then be fetched using ovirt_resource_refresh() or
+ * ovirt_resource_refresh_async().
+ *
+ * Return value: (transfer full): a #OvirtCluster representing cluster the @host
+ * belongs to.
+ */
+OvirtCluster *ovirt_host_get_cluster(OvirtHost *host)
+{
+ g_return_val_if_fail(OVIRT_IS_HOST(host), NULL);
+ g_return_val_if_fail(host->priv->cluster_id != NULL, NULL);
+ return ovirt_cluster_new_from_id(host->priv->cluster_id, get_cluster_href(host));
+}
diff --git a/govirt/ovirt-host.h b/govirt/ovirt-host.h
index 91441f6..cdf702c 100644
--- a/govirt/ovirt-host.h
+++ b/govirt/ovirt-host.h
@@ -60,6 +60,7 @@ GType ovirt_host_get_type(void);

OvirtHost *ovirt_host_new(void);
OvirtCollection *ovirt_host_get_vms(OvirtHost *host);
+OvirtCluster *ovirt_host_get_cluster(OvirtHost *host);

G_END_DECLS

93
SOURCES/0025-cluster-Introduce-ovirt_cluster_get_data_center.patch

@ -0,0 +1,93 @@ @@ -0,0 +1,93 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: "Eduardo Lima (Etrunko)" <etrunko@redhat.com>
Date: Thu, 13 Jul 2017 17:49:36 -0300
Subject: [PATCH] cluster: Introduce ovirt_cluster_get_data_center()

This function can be used to retrieve the data center associated with
the cluster.

Signed-off-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
---
govirt/govirt.sym | 1 +
govirt/ovirt-cluster.c | 33 ++++++++++++++++++++++++++++++++-
govirt/ovirt-cluster.h | 1 +
3 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/govirt/govirt.sym b/govirt/govirt.sym
index 243ce0b..9806033 100644
--- a/govirt/govirt.sym
+++ b/govirt/govirt.sym
@@ -121,6 +121,7 @@ GOVIRT_0.3.2 {
ovirt_api_search_vms;
ovirt_api_search_vm_pools;

+ ovirt_cluster_get_data_center;
ovirt_cluster_get_type;
ovirt_cluster_get_hosts;
ovirt_cluster_new;
diff --git a/govirt/ovirt-cluster.c b/govirt/ovirt-cluster.c
index 83b0fa1..4aaf6b1 100644
--- a/govirt/ovirt-cluster.c
+++ b/govirt/ovirt-cluster.c
@@ -42,6 +42,18 @@ enum {
PROP_DATA_CENTER_ID,
};

+static const char *get_data_center_href(OvirtCluster *cluster)
+{
+ if (cluster->priv->data_center_href == NULL &&
+ cluster->priv->data_center_id != NULL) {
+ cluster->priv->data_center_href = g_strdup_printf("%s/%s",
+ "/ovirt-engine/api/data_centers",
+ cluster->priv->data_center_id);
+ }
+
+ return cluster->priv->data_center_href;
+}
+
static void ovirt_cluster_get_property(GObject *object,
guint prop_id,
GValue *value,
@@ -51,7 +63,7 @@ static void ovirt_cluster_get_property(GObject *object,

switch (prop_id) {
case PROP_DATA_CENTER_HREF:
- g_value_set_string(value, cluster->priv->data_center_href);
+ g_value_set_string(value, get_data_center_href(cluster));
break;
case PROP_DATA_CENTER_ID:
g_value_set_string(value, cluster->priv->data_center_id);
@@ -213,3 +225,22 @@ OvirtCollection *ovirt_cluster_get_hosts(OvirtCluster *cluster)
return cluster->priv->hosts;
}

+
+/**
+ * ovirt_cluster_get_data_center:
+ * @cluster: a #OvirtCluster
+ *
+ * Gets a #OvirtCluster representing the data center the cluster belongs
+ * to. This method does not initiate any network activity, the remote data center must
+ * be then be fetched using ovirt_resource_refresh() or
+ * ovirt_resource_refresh_async().
+ *
+ * Return value: (transfer full): a #OvirtDataCenter representing data center
+ * the @host belongs to.
+ */
+OvirtDataCenter *ovirt_cluster_get_data_center(OvirtCluster *cluster)
+{
+ g_return_val_if_fail(OVIRT_IS_CLUSTER(cluster), NULL);
+ g_return_val_if_fail(cluster->priv->data_center_id != NULL, NULL);
+ return ovirt_data_center_new_from_id(cluster->priv->data_center_id, get_data_center_href(cluster));
+}
diff --git a/govirt/ovirt-cluster.h b/govirt/ovirt-cluster.h
index 9505e8c..cdd54b7 100644
--- a/govirt/ovirt-cluster.h
+++ b/govirt/ovirt-cluster.h
@@ -60,6 +60,7 @@ GType ovirt_cluster_get_type(void);

OvirtCluster *ovirt_cluster_new(void);
OvirtCollection *ovirt_cluster_get_hosts(OvirtCluster *cluster);
+OvirtDataCenter *ovirt_cluster_get_data_center(OvirtCluster *cluster);

G_END_DECLS

93
SOURCES/0026-storage-domain-Retrieve-data-center-ids.patch

@ -0,0 +1,93 @@ @@ -0,0 +1,93 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: "Eduardo Lima (Etrunko)" <etrunko@redhat.com>
Date: Thu, 13 Apr 2017 15:26:41 -0300
Subject: [PATCH] storage-domain: Retrieve data center ids

Storage domains can be part of one or more data centers, so we use a
GStrv to store each id.

Signed-off-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
---
govirt/ovirt-storage-domain.c | 27 ++++++++++++++++++++++++++-
1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/govirt/ovirt-storage-domain.c b/govirt/ovirt-storage-domain.c
index e255565..718c1d2 100644
--- a/govirt/ovirt-storage-domain.c
+++ b/govirt/ovirt-storage-domain.c
@@ -30,6 +30,7 @@

struct _OvirtStorageDomainPrivate {
OvirtCollection *files;
+ GStrv data_center_ids;

OvirtStorageDomainType type;
gboolean is_master;
@@ -50,7 +51,8 @@ enum {
PROP_USED,
PROP_COMMITTED,
PROP_VERSION,
- PROP_STATE
+ PROP_STATE,
+ PROP_DATA_CENTER_IDS,
};

static void ovirt_storage_domain_get_property(GObject *object,
@@ -82,6 +84,9 @@ static void ovirt_storage_domain_get_property(GObject *object,
case PROP_STATE:
g_value_set_enum(value, domain->priv->state);
break;
+ case PROP_DATA_CENTER_IDS:
+ g_value_set_boxed(value, domain->priv->data_center_ids);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
@@ -117,6 +122,10 @@ static void ovirt_storage_domain_set_property(GObject *object,
case PROP_STATE:
domain->priv->state = g_value_get_enum(value);
break;
+ case PROP_DATA_CENTER_IDS:
+ g_strfreev(domain->priv->data_center_ids);
+ domain->priv->data_center_ids = g_value_dup_boxed(value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
@@ -130,6 +139,7 @@ ovirt_storage_domain_dispose(GObject *obj)
OvirtStorageDomain *domain = OVIRT_STORAGE_DOMAIN(obj);

g_clear_object(&domain->priv->files);
+ g_clear_pointer(&domain->priv->data_center_ids, g_strfreev);

G_OBJECT_CLASS(ovirt_storage_domain_parent_class)->dispose(obj);
}
@@ -170,6 +180,11 @@ static gboolean ovirt_storage_domain_init_from_xml(OvirtResource *resource,
.type = OVIRT_TYPE_STORAGE_DOMAIN_STATE,
.xml_path = "status/state",
},
+ { .prop_name = "data-center-ids",
+ .type = G_TYPE_STRV,
+ .xml_path = "data_centers",
+ .xml_attr = "id",
+ },
{ NULL , }
};

@@ -274,6 +289,16 @@ static void ovirt_storage_domain_class_init(OvirtStorageDomainClass *klass)
g_object_class_install_property(object_class,
PROP_STATE,
param_spec);
+
+ param_spec = g_param_spec_boxed("data-center-ids",
+ "Data Center Ids",
+ "Ids of Data Centers for this Storage Domain",
+ G_TYPE_STRV,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property(object_class,
+ PROP_DATA_CENTER_IDS,
+ param_spec);
}

static void ovirt_storage_domain_init(OvirtStorageDomain *domain)

26
SOURCES/0027-Add-missing-include-in-govirt.h.patch

@ -0,0 +1,26 @@ @@ -0,0 +1,26 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: "Eduardo Lima (Etrunko)" <etrunko@redhat.com>
Date: Thu, 3 Aug 2017 16:53:09 -0300
Subject: [PATCH] Add missing #include in govirt.h

Signed-off-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
---
govirt/govirt.h | 3 +++
1 file changed, 3 insertions(+)

diff --git a/govirt/govirt.h b/govirt/govirt.h
index fb7756f..9c92318 100644
--- a/govirt/govirt.h
+++ b/govirt/govirt.h
@@ -25,8 +25,11 @@
#include <govirt/ovirt-enum-types.h>
#include <govirt/ovirt-api.h>
#include <govirt/ovirt-cdrom.h>
+#include <govirt/ovirt-cluster.h>
#include <govirt/ovirt-collection.h>
+#include <govirt/ovirt-data-center.h>
#include <govirt/ovirt-error.h>
+#include <govirt/ovirt-host.h>
#include <govirt/ovirt-options.h>
#include <govirt/ovirt-proxy.h>
#include <govirt/ovirt-resource.h>

23
SOURCES/0028-resource-Fix-ovirt_resource_rest_call_sync-return-va.patch

@ -0,0 +1,23 @@ @@ -0,0 +1,23 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Christophe Fergeau <cfergeau@redhat.com>
Date: Tue, 25 Jul 2017 17:34:31 +0200
Subject: [PATCH] resource: Fix ovirt_resource_rest_call_sync return value

Upon success, ovirt_resource_rest_call_sync() was always returning
NULL, which is not what is expected. This, among other things, made
ovirt_resource_refresh() non-functional.
---
govirt/ovirt-resource.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/govirt/ovirt-resource.c b/govirt/ovirt-resource.c
index 1413a77..0c750ac 100644
--- a/govirt/ovirt-resource.c
+++ b/govirt/ovirt-resource.c
@@ -499,7 +499,7 @@ G_GNUC_INTERNAL RestXmlNode *ovirt_resource_rest_call_sync(OvirtRestCall *call,
return NULL;
}

- return root;
+ return ovirt_rest_xml_node_from_call(REST_PROXY_CALL(call));
}

39
SOURCES/0029-resource-Fix-ovirt_resource_rest_call_sync-crash-on-.patch

@ -0,0 +1,39 @@ @@ -0,0 +1,39 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Christophe Fergeau <cfergeau@redhat.com>
Date: Tue, 25 Jul 2017 17:36:05 +0200
Subject: [PATCH] resource: Fix ovirt_resource_rest_call_sync() crash on 404

When the REST call fails, we do not always get an XML answer from oVirt
describing the failure in more details. In particular, this is the case
when we hit a 404. In such situations, we'd be crashing because we'd
attempt to dereference a NULL pointer.
---
govirt/ovirt-resource.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/govirt/ovirt-resource.c b/govirt/ovirt-resource.c
index 0c750ac..0f4a129 100644
--- a/govirt/ovirt-resource.c
+++ b/govirt/ovirt-resource.c
@@ -485,16 +485,17 @@ G_GNUC_INTERNAL RestXmlNode *ovirt_resource_rest_call_sync(OvirtRestCall *call,
GError *local_error = NULL;

root = ovirt_rest_xml_node_from_call(REST_PROXY_CALL(call));
- ovirt_utils_gerror_from_xml_fault(root, &local_error);
+ if (root != NULL) {
+ ovirt_utils_gerror_from_xml_fault(root, &local_error);
+ rest_xml_node_unref(root);
+ }
if (local_error != NULL) {
g_clear_error(error);
g_warning("Error while updating resource");
g_warning("message: %s", local_error->message);
g_propagate_error(error, local_error);
}
- if (root != NULL) {
- rest_xml_node_unref(root);
- }
+ g_warn_if_fail(error == NULL || *error != NULL);

return NULL;
}

29
SOURCES/0030-resource-Fix-ovirt_resource_init_from_xml_real-preco.patch

@ -0,0 +1,29 @@ @@ -0,0 +1,29 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Christophe Fergeau <cfergeau@redhat.com>
Date: Mon, 11 Sep 2017 15:01:59 +0200
Subject: [PATCH] resource: Fix ovirt_resource_init_from_xml_real precondition

When ovirt_resource_init_from_xml_real is called, the current value of
OvirtResource::xml-node is not very relevant, what matters is whether
the passed in xml node is NULL or not.

This updates the test-govirt test case to call
ovirt_resource_refresh(ovirt_vm_get_cluster()) as this triggers this
precondition failure.
---
govirt/ovirt-resource.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/govirt/ovirt-resource.c b/govirt/ovirt-resource.c
index 0f4a129..ad5e8ca 100644
--- a/govirt/ovirt-resource.c
+++ b/govirt/ovirt-resource.c
@@ -422,7 +422,7 @@ static gboolean ovirt_resource_init_from_xml_real(OvirtResource *resource,
*/
is_api = OVIRT_IS_API(resource);

- g_return_val_if_fail(resource->priv->xml != NULL, FALSE);
+ g_return_val_if_fail(node != NULL, FALSE);

guid = rest_xml_node_get_attr(node, "id");
if ((guid == NULL) && !is_api) {

61
SOURCES/0031-resource-Update-xml-node-in-ovirt_resource_init_from.patch

@ -0,0 +1,61 @@ @@ -0,0 +1,61 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Christophe Fergeau <cfergeau@redhat.com>
Date: Mon, 11 Sep 2017 14:59:08 +0200
Subject: [PATCH] resource: Update xml node in
ovirt_resource_init_from_xml_real

ovirt_resource_init_from_xml_real is called indirectly when
ovirt_resource_refresh() is used. For some reason, it updates
the various OvirtResource properties with the new XML node content, but
OvirtResource::xml-node is not set to be the new node.
This commit fixes this inconsistent state by making sure
OvirtResource::xml-node is changed to point to the new node.
---
govirt/ovirt-resource.c | 19 +++++++++++++------
1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/govirt/ovirt-resource.c b/govirt/ovirt-resource.c
index ad5e8ca..1984b1d 100644
--- a/govirt/ovirt-resource.c
+++ b/govirt/ovirt-resource.c
@@ -97,6 +97,15 @@ static void ovirt_resource_get_property(GObject *object,
}
}

+static void ovirt_resource_set_xml_node(OvirtResource *resource,
+ RestXmlNode *node)
+{
+ g_clear_pointer(&resource->priv->xml, &rest_xml_node_unref);
+ if (node != NULL) {
+ resource->priv->xml = rest_xml_node_ref(node);
+ }
+}
+
static void ovirt_resource_set_property(GObject *object,
guint prop_id,
const GValue *value,
@@ -121,13 +130,10 @@ static void ovirt_resource_set_property(GObject *object,
g_free(resource->priv->description);
resource->priv->description = g_value_dup_string(value);
break;
- case PROP_XML_NODE: {
- if (resource->priv->xml != NULL) {
- g_boxed_free(REST_TYPE_XML_NODE, resource->priv->xml);
- }
- resource->priv->xml = g_value_dup_boxed(value);
+ case PROP_XML_NODE:
+ ovirt_resource_set_xml_node(OVIRT_RESOURCE(object),
+ g_value_get_boxed(value));
break;
- }
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
}
@@ -438,6 +444,7 @@ static gboolean ovirt_resource_init_from_xml_real(OvirtResource *resource,
return FALSE;
}

+ ovirt_resource_set_xml_node(resource, node);
g_object_set(G_OBJECT(resource), "guid", guid, "href", href, NULL);

ovirt_resource_set_name_from_xml(resource, node);

151
SOURCES/0032-utils-Drop-type-member-from-OvirtXmlElement-struct.patch

@ -0,0 +1,151 @@ @@ -0,0 +1,151 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: "Eduardo Lima (Etrunko)" <etrunko@redhat.com>
Date: Thu, 18 May 2017 17:21:10 -0300
Subject: [PATCH] utils: Drop 'type' member from OvirtXmlElement struct

Instead of passing the type, it is possible to get it using by calling
g_object_class_find_property(). All users have been updated accordingly.

Signed-off-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
---
govirt/ovirt-cluster.c | 2 --
govirt/ovirt-host.c | 2 --
govirt/ovirt-storage-domain.c | 8 --------
govirt/ovirt-utils.c | 8 ++++++--
govirt/ovirt-utils.h | 1 -
govirt/ovirt-vm.c | 4 ----
6 files changed, 6 insertions(+), 19 deletions(-)

diff --git a/govirt/ovirt-cluster.c b/govirt/ovirt-cluster.c
index 4aaf6b1..ae25d63 100644
--- a/govirt/ovirt-cluster.c
+++ b/govirt/ovirt-cluster.c
@@ -115,12 +115,10 @@ static gboolean ovirt_cluster_init_from_xml(OvirtResource *resource,
OvirtResourceClass *parent_class;
OvirtXmlElement cluster_elements[] = {
{ .prop_name = "data-center-href",
- .type = G_TYPE_STRING,
.xml_path = "data_center",
.xml_attr = "href",
},
{ .prop_name = "data-center-id",
- .type = G_TYPE_STRING,
.xml_path = "data_center",
.xml_attr = "id",
},
diff --git a/govirt/ovirt-host.c b/govirt/ovirt-host.c
index 191b360..1570cba 100644
--- a/govirt/ovirt-host.c
+++ b/govirt/ovirt-host.c
@@ -116,12 +116,10 @@ static gboolean ovirt_host_init_from_xml(OvirtResource *resource,
OvirtResourceClass *parent_class;
OvirtXmlElement host_elements[] = {
{ .prop_name = "cluster-href",
- .type = G_TYPE_STRING,
.xml_path = "cluster",
.xml_attr = "href",
},
{ .prop_name = "cluster-id",
- .type = G_TYPE_STRING,
.xml_path = "cluster",
.xml_attr = "id",
},
diff --git a/govirt/ovirt-storage-domain.c b/govirt/ovirt-storage-domain.c
index 718c1d2..a9078f4 100644
--- a/govirt/ovirt-storage-domain.c
+++ b/govirt/ovirt-storage-domain.c
@@ -153,35 +153,27 @@ static gboolean ovirt_storage_domain_init_from_xml(OvirtResource *resource,
OvirtResourceClass *parent_class;
OvirtXmlElement storage_domain_elements[] = {
{ .prop_name = "type",
- .type = OVIRT_TYPE_STORAGE_DOMAIN_TYPE,
.xml_path = "type",
},
{ .prop_name = "master",
- .type = G_TYPE_BOOLEAN,
.xml_path = "master",
},
{ .prop_name = "available",
- .type = G_TYPE_UINT64,
.xml_path = "available",
},
{ .prop_name = "used",
- .type = G_TYPE_UINT64,
.xml_path = "used",
},
{ .prop_name = "committed",
- .type = G_TYPE_UINT64,
.xml_path = "committed",
},
{ .prop_name = "version",
- .type = OVIRT_TYPE_STORAGE_DOMAIN_FORMAT_VERSION,
.xml_path = "storage_format",
},
{ .prop_name = "state",
- .type = OVIRT_TYPE_STORAGE_DOMAIN_STATE,
.xml_path = "status/state",
},
{ .prop_name = "data-center-ids",
- .type = G_TYPE_STRV,
.xml_path = "data_centers",
.xml_attr = "id",
},
diff --git a/govirt/ovirt-utils.c b/govirt/ovirt-utils.c
index 1898862..501acb9 100644
--- a/govirt/ovirt-utils.c
+++ b/govirt/ovirt-utils.c
@@ -207,9 +207,13 @@ ovirt_rest_xml_node_parse(RestXmlNode *node,

for (;elements->xml_path != NULL; elements++) {
GValue value = { 0, };
+ GParamSpec *prop;

- g_value_init(&value, elements->type);
- if (_set_property_value_from_type(&value, elements->type, elements->xml_path, elements->xml_attr, node))
+ prop = g_object_class_find_property(G_OBJECT_GET_CLASS(object), elements->prop_name);
+ g_return_val_if_fail(prop != NULL, FALSE);
+
+ g_value_init(&value, prop->value_type);
+ if (_set_property_value_from_type(&value, prop->value_type, elements->xml_path, elements->xml_attr, node))
g_object_set_property(object, elements->prop_name, &value);
g_value_unset(&value);
}
diff --git a/govirt/ovirt-utils.h b/govirt/ovirt-utils.h
index 545847a..e03f453 100644
--- a/govirt/ovirt-utils.h
+++ b/govirt/ovirt-utils.h
@@ -31,7 +31,6 @@ typedef struct _OvirtXmlElement OvirtXmlElement;
struct _OvirtXmlElement
{
const char *prop_name;
- GType type;
const char *xml_path;
const char *xml_attr; /* if NULL, retrieve node content instead of attribute */
};
diff --git a/govirt/ovirt-vm.c b/govirt/ovirt-vm.c
index 70b6f3a..36ffd35 100644
--- a/govirt/ovirt-vm.c
+++ b/govirt/ovirt-vm.c
@@ -184,22 +184,18 @@ static gboolean ovirt_vm_init_from_xml(OvirtResource *resource,
OvirtResourceClass *parent_class;
OvirtXmlElement vm_elements[] = {
{ .prop_name = "host-href",
- .type = G_TYPE_STRING,
.xml_path = "host",
.xml_attr = "href",
},
{ .prop_name = "host-id",
- .type = G_TYPE_STRING,
.xml_path = "host",
.xml_attr = "id",
},
{ .prop_name = "cluster-href",
- .type = G_TYPE_STRING,
.xml_path = "cluster",
.xml_attr = "href",
},
{ .prop_name = "cluster-id",
- .type = G_TYPE_STRING,
.xml_path = "cluster",
.xml_attr = "id",
},

39
SOURCES/0033-utils-Support-G_TYPE_UINT-in-_set_property_value_fro.patch

@ -0,0 +1,39 @@ @@ -0,0 +1,39 @@
From 7eae90f67d00bf36c0a9c56cf3c9e4fdc7d02494 Mon Sep 17 00:00:00 2001
From: "Eduardo Lima (Etrunko)" <etrunko@redhat.com>
Date: Wed, 10 May 2017 15:53:12 -0300
Subject: [PATCH] utils: Support G_TYPE_UINT in _set_property_value_from_type()

This type will mostly be used to parse the XML elements for
OvirtVmDisplay.

Signed-off-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
---
govirt/ovirt-utils.c | 6 ++++++
1 file changed, 6 insertions(+)

diff --git a/govirt/ovirt-utils.c b/govirt/ovirt-utils.c
index 501acb9..af1dfc6 100644
--- a/govirt/ovirt-utils.c
+++ b/govirt/ovirt-utils.c
@@ -23,6 +23,7 @@
#include <config.h>

#include <errno.h>
+#include <stdlib.h>
#include <string.h>

#include <glib/gi18n-lib.h>
@@ -182,6 +183,11 @@ _set_property_value_from_type(GValue *value,
g_value_set_string(value, value_str);
break;
}
+ case G_TYPE_UINT: {
+ guint uint_value = strtoul(value_str, NULL, 0);
+ g_value_set_uint(value, uint_value);
+ break;
+ }
case G_TYPE_UINT64: {
guint64 int64_value = g_ascii_strtoull(value_str, NULL, 0);
g_value_set_uint64(value, int64_value);
--
2.14.4

28
SOURCES/0034-utils-Improve-log-message-when-subnode-is-not-found.patch

@ -0,0 +1,28 @@ @@ -0,0 +1,28 @@
From 5a41846ba6e0d88a0a641caa214703336e2b2820 Mon Sep 17 00:00:00 2001
From: "Eduardo Lima (Etrunko)" <etrunko@redhat.com>
Date: Mon, 18 Sep 2017 10:47:13 -0300
Subject: [PATCH] utils: Improve log message when subnode is not found

Signed-off-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
---
govirt/ovirt-utils.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/govirt/ovirt-utils.c b/govirt/ovirt-utils.c
index af1dfc6..a60c754 100644
--- a/govirt/ovirt-utils.c
+++ b/govirt/ovirt-utils.c
@@ -63,9 +63,10 @@ ovirt_rest_xml_node_find(RestXmlNode *node, const char *path)
pathv = g_strsplit(path, "/", -1);

for (i = 0; i < g_strv_length(pathv); ++i) {
+ gchar *name = node->name;
node = rest_xml_node_find(node, pathv[i]);
if (node == NULL) {
- g_debug("could not find XML node '%s'", pathv[i]);
+ g_debug("could not find subnode '%s' of XML node '%s' (search: %s)", pathv[i], name, path);
break;
}
}
--
2.14.4

92
SOURCES/0035-utils-Factor-out-basic-value-type-setting-from-_set_.patch

@ -0,0 +1,92 @@ @@ -0,0 +1,92 @@
From 1bff3d3ca4101639e659c8649731020e7a5c9c10 Mon Sep 17 00:00:00 2001
From: "Eduardo Lima (Etrunko)" <etrunko@redhat.com>
Date: Tue, 3 Oct 2017 17:32:03 -0300
Subject: [PATCH] utils: Factor out basic value type setting from
_set_property_value_from_type()

A simple cosmetic enhancement with the hope to improve code readability.

Signed-off-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
---
govirt/ovirt-utils.c | 59 ++++++++++++++++++++++++++++++----------------------
1 file changed, 34 insertions(+), 25 deletions(-)

diff --git a/govirt/ovirt-utils.c b/govirt/ovirt-utils.c
index a60c754..a0146fd 100644
--- a/govirt/ovirt-utils.c
+++ b/govirt/ovirt-utils.c
@@ -134,6 +134,39 @@ ovirt_rest_xml_node_get_str_array_from_path(RestXmlNode *node, const char *path,
return (GStrv) g_array_free(array, FALSE);
}

+static gboolean
+_set_property_value_from_basic_type(GValue *value,
+ GType type,
+ const char *value_str)
+{
+ switch(type) {
+ case G_TYPE_BOOLEAN: {
+ gboolean bool_value = ovirt_utils_boolean_from_string(value_str);
+ g_value_set_boolean(value, bool_value);
+ return TRUE;
+ }
+ case G_TYPE_STRING: {
+ g_value_set_string(value, value_str);
+ return TRUE;
+ }
+ case G_TYPE_UINT: {
+ guint uint_value = strtoul(value_str, NULL, 0);
+ g_value_set_uint(value, uint_value);
+ return TRUE;
+ }
+ case G_TYPE_UINT64: {
+ guint64 int64_value = g_ascii_strtoull(value_str, NULL, 0);
+ g_value_set_uint64(value, int64_value);
+ return TRUE;
+ }
+ default: {
+ g_warning("Unexpected type '%s' with value '%s'", g_type_name(type), value_str);
+ }
+ }
+
+ return FALSE;
+}
+
static gboolean
_set_property_value_from_type(GValue *value,
GType type,
@@ -174,31 +207,7 @@ _set_property_value_from_type(GValue *value,
goto end;
}

- switch(type) {
- case G_TYPE_BOOLEAN: {
- gboolean bool_value = ovirt_utils_boolean_from_string(value_str);
- g_value_set_boolean(value, bool_value);
- break;
- }
- case G_TYPE_STRING: {
- g_value_set_string(value, value_str);
- break;
- }
- case G_TYPE_UINT: {
- guint uint_value = strtoul(value_str, NULL, 0);
- g_value_set_uint(value, uint_value);
- break;
- }
- case G_TYPE_UINT64: {
- guint64 int64_value = g_ascii_strtoull(value_str, NULL, 0);
- g_value_set_uint64(value, int64_value);
- break;
- }
- default: {
- g_warning("Unexpected type '%s' with value '%s'", g_type_name(type), value_str);
- ret = FALSE;
- }
- }
+ ret = _set_property_value_from_basic_type(value, type, value_str);

end:
return ret;
--
2.14.4

54
SOURCES/0036-utils-Get-enum-default-value-from-GParamSpec.patch

@ -0,0 +1,54 @@ @@ -0,0 +1,54 @@
From 290692dcf6d572e86a2a90ff87f666ea148eb602 Mon Sep 17 00:00:00 2001
From: "Eduardo Lima (Etrunko)" <etrunko@redhat.com>
Date: Tue, 3 Oct 2017 17:51:41 -0300
Subject: [PATCH] utils: Get enum default value from GParamSpec

Instead of assuming 0 as the default value, use the one specified during
property creation time with g_param_spec_enum().

Signed-off-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
---
govirt/ovirt-utils.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/govirt/ovirt-utils.c b/govirt/ovirt-utils.c
index a0146fd..dfaf09d 100644
--- a/govirt/ovirt-utils.c
+++ b/govirt/ovirt-utils.c
@@ -169,13 +169,14 @@ _set_property_value_from_basic_type(GValue *value,

static gboolean
_set_property_value_from_type(GValue *value,
- GType type,
+ GParamSpec *prop,
const char *path,
const char *attr,
RestXmlNode *node)
{
gboolean ret = TRUE;
const char *value_str;
+ GType type = prop->value_type;

if (g_type_is_a(type, OVIRT_TYPE_RESOURCE)) {
OvirtResource *resource_value = ovirt_resource_new_from_xml(type, node, NULL);
@@ -202,7 +203,8 @@ _set_property_value_from_type(GValue *value,
return FALSE;

if (G_TYPE_IS_ENUM(type)) {
- int enum_value = ovirt_utils_genum_get_value(type, value_str, 0);
+ GParamSpecEnum *enum_prop = G_PARAM_SPEC_ENUM(prop);
+ int enum_value = ovirt_utils_genum_get_value(type, value_str, enum_prop->default_value);
g_value_set_enum(value, enum_value);
goto end;
}
@@ -229,7 +231,7 @@ ovirt_rest_xml_node_parse(RestXmlNode *node,
g_return_val_if_fail(prop != NULL, FALSE);

g_value_init(&value, prop->value_type);
- if (_set_property_value_from_type(&value, prop->value_type, elements->xml_path, elements->xml_attr, node))
+ if (_set_property_value_from_type(&value, prop, elements->xml_path, elements->xml_attr, node))
g_object_set_property(object, elements->prop_name, &value);
g_value_unset(&value);
}
--
2.14.4

81
SOURCES/0037-vm-Set-vm-state-property-using-OvirtXmlElement-struc.patch

@ -0,0 +1,81 @@ @@ -0,0 +1,81 @@
From 039c8d8bc0aa49ea3bd34fc190afc844d68a6e41 Mon Sep 17 00:00:00 2001
From: "Eduardo Lima (Etrunko)" <etrunko@redhat.com>
Date: Thu, 4 May 2017 18:23:39 -0300
Subject: [PATCH] vm: Set vm state property using OvirtXmlElement struct

It was required to change the default value of the enum property to
OVIRT_VM_STATE_UNKNOWN, so that it will be set by
ovirt_rest_xml_node_parse() function in case of error.

Signed-off-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
---
govirt/ovirt-vm-xml.c | 30 +-----------------------------
govirt/ovirt-vm.c | 5 ++++-
2 files changed, 5 insertions(+), 30 deletions(-)

diff --git a/govirt/ovirt-vm-xml.c b/govirt/ovirt-vm-xml.c
index 9990262..25f50f3 100644
--- a/govirt/ovirt-vm-xml.c
+++ b/govirt/ovirt-vm-xml.c
@@ -138,35 +138,7 @@ static gboolean vm_set_display_from_xml(OvirtVm *vm,
return TRUE;
}

-static gboolean vm_set_state_from_xml(OvirtVm *vm, RestXmlNode *node)
-{
- RestXmlNode *state_node;
-
- state_node = rest_xml_node_find(node, "status");
- if (state_node == NULL) {
- g_debug("Could not find 'status' node");
- return FALSE;
- }
- state_node = rest_xml_node_find(state_node, "state");
- if (state_node != NULL) {
- int state;
-
- g_return_val_if_fail(state_node->content != NULL, FALSE);
- state = ovirt_utils_genum_get_value(OVIRT_TYPE_VM_STATE,
- state_node->content,
- OVIRT_VM_STATE_UNKNOWN);
- g_object_set(G_OBJECT(vm), "state", state, NULL);
-
- return TRUE;
- }
-
- return FALSE;
-}
-
G_GNUC_INTERNAL gboolean ovirt_vm_refresh_from_xml(OvirtVm *vm, RestXmlNode *node)
{
- vm_set_state_from_xml(vm, node);
- vm_set_display_from_xml(vm, node);
-
- return TRUE;
+ return vm_set_display_from_xml(vm, node);
}
diff --git a/govirt/ovirt-vm.c b/govirt/ovirt-vm.c
index 36ffd35..f30022d 100644
--- a/govirt/ovirt-vm.c
+++ b/govirt/ovirt-vm.c
@@ -199,6 +199,9 @@ static gboolean ovirt_vm_init_from_xml(OvirtResource *resource,
.xml_path = "cluster",
.xml_attr = "id",
},
+ { .prop_name = "state",
+ .xml_path = "status/state",
+ },
{ NULL, },
};

@@ -233,7 +236,7 @@ static void ovirt_vm_class_init(OvirtVmClass *klass)
"State",
"Virtual Machine State",
OVIRT_TYPE_VM_STATE,
- OVIRT_VM_STATE_DOWN,
+ OVIRT_VM_STATE_UNKNOWN,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
g_object_class_install_property(object_class,
--
2.14.4

189
SOURCES/0038-vm-Set-values-of-OvirtVmDisplay-using-OvirtXmlElemen.patch

@ -0,0 +1,189 @@ @@ -0,0 +1,189 @@
From b8b0d03e43bee40ad15fa4c3aa6ca8b07ca98e31 Mon Sep 17 00:00:00 2001
From: "Eduardo Lima (Etrunko)" <etrunko@redhat.com>
Date: Wed, 10 May 2017 15:48:09 -0300
Subject: [PATCH] vm: Set values of OvirtVmDisplay using OvirtXmlElement struct

This required the addition of OVIRT_VM_DISPLAY_INVALID to the
OvirtVmDisplayType enum as the default value.

The value of the 'type' property of OvirtVmDisplay is tested after the
parsing is done, to ensure it is either vnc or spice.

Signed-off-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
---
govirt/ovirt-vm-display.c | 2 +-
govirt/ovirt-vm-display.h | 3 +-
govirt/ovirt-vm-xml.c | 118 ++++++++++++++--------------------------------
3 files changed, 38 insertions(+), 85 deletions(-)

diff --git a/govirt/ovirt-vm-display.c b/govirt/ovirt-vm-display.c
index 37e042a..b03c303 100644
--- a/govirt/ovirt-vm-display.c
+++ b/govirt/ovirt-vm-display.c
@@ -197,7 +197,7 @@ static void ovirt_vm_display_class_init(OvirtVmDisplayClass *klass)
"Type",
"Display Type",
OVIRT_TYPE_VM_DISPLAY_TYPE,
- OVIRT_VM_DISPLAY_SPICE,
+ OVIRT_VM_DISPLAY_INVALID,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
g_object_class_install_property(object_class,
diff --git a/govirt/ovirt-vm-display.h b/govirt/ovirt-vm-display.h
index f7eb310..38ef9b7 100644
--- a/govirt/ovirt-vm-display.h
+++ b/govirt/ovirt-vm-display.h
@@ -55,7 +55,8 @@ struct _OvirtVmDisplayClass

typedef enum {
OVIRT_VM_DISPLAY_SPICE,
- OVIRT_VM_DISPLAY_VNC
+ OVIRT_VM_DISPLAY_VNC,
+ OVIRT_VM_DISPLAY_INVALID,
} OvirtVmDisplayType;

GType ovirt_vm_display_get_type(void);
diff --git a/govirt/ovirt-vm-xml.c b/govirt/ovirt-vm-xml.c
index 25f50f3..0603427 100644
--- a/govirt/ovirt-vm-xml.c
+++ b/govirt/ovirt-vm-xml.c
@@ -33,102 +33,54 @@
static gboolean vm_set_display_from_xml(OvirtVm *vm,
RestXmlNode *root)
{
- RestXmlNode *node;
OvirtVmDisplay *display;
- const char *display_key = g_intern_string("display");
- const char *type_key = g_intern_string("type");
- const char *address_key = g_intern_string("address");
- const char *port_key = g_intern_string("port");
- const char *secure_port_key = g_intern_string("secure_port");
- const char *monitors_key = g_intern_string("monitors");
- const char *certificate_key = g_intern_string("certificate");
- const char *smartcard_key = g_intern_string("smartcard_enabled");
- const char *allow_override_key = g_intern_string("allow_override");
- const char *proxy_key = g_intern_string("proxy");
+ OvirtVmDisplayType type;
+ OvirtXmlElement display_elements[] = {
+ { .prop_name = "type",
+ .xml_path = "type",
+ },
+ { .prop_name = "address",
+ .xml_path = "address",
+ },
+ { .prop_name = "port",
+ .xml_path = "port",
+ },
+ { .prop_name = "secure-port",
+ .xml_path = "secure_port",
+ },
+ { .prop_name = "monitor-count",
+ .xml_path = "monitors",
+ },
+ { .prop_name = "smartcard",
+ .xml_path = "smartcard_enabled",
+ },
+ { .prop_name = "allow-override",
+ .xml_path = "allow_override",
+ },
+ { .prop_name = "host-subject",
+ .xml_path = "certificate/subject",
+ },
+ { .prop_name = "proxy-url",
+ .xml_path = "proxy",
+ },
+ { NULL, },
+ };

if (root == NULL) {
return FALSE;
}
- root = g_hash_table_lookup(root->children, display_key);
+ root = rest_xml_node_find(root, "display");
if (root == NULL) {
g_debug("Could not find 'display' node");
return FALSE;
}
display = ovirt_vm_display_new();
-
- node = g_hash_table_lookup(root->children, type_key);
- g_return_val_if_fail(node != NULL, FALSE);
- if (g_strcmp0(node->content, "spice") == 0) {
- g_object_set(G_OBJECT(display), "type", OVIRT_VM_DISPLAY_SPICE, NULL);
- } else if (g_strcmp0(node->content, "vnc") == 0) {
- g_object_set(G_OBJECT(display), "type", OVIRT_VM_DISPLAY_VNC, NULL);
- } else {
- g_warning("Unknown display type: %s", node->content);
+ ovirt_rest_xml_node_parse(root, G_OBJECT(display), display_elements);
+ g_object_get(G_OBJECT(display), "type", &type, NULL);
+ if (type == OVIRT_VM_DISPLAY_INVALID) {
return FALSE;
}

- node = g_hash_table_lookup(root->children, monitors_key);
- g_return_val_if_fail(node != NULL, FALSE);
- g_object_set(G_OBJECT(display),
- "monitor-count", strtoul(node->content, NULL, 0),
- NULL);
-
- /* on non started VMs, these 2 values will not be available */
- node = g_hash_table_lookup(root->children, address_key);
- if (node != NULL) {
- g_object_set(G_OBJECT(display), "address", node->content, NULL);
- }
-
- node = g_hash_table_lookup(root->children, port_key);
- if (node != NULL) {
- g_object_set(G_OBJECT(display),
- "port", strtoul(node->content, NULL, 0),
- NULL);
- }
-
- node = g_hash_table_lookup(root->children, secure_port_key);
- if (node != NULL) {
- g_object_set(G_OBJECT(display),
- "secure-port", strtoul(node->content, NULL, 0),
- NULL);
- }
-
- node = g_hash_table_lookup(root->children, smartcard_key);
- if (node != NULL) {
- gboolean smartcard;
-
- smartcard = (g_strcmp0(node->content, "true") == 0);
- g_object_set(G_OBJECT(display),
- "smartcard", smartcard,
- NULL);
- }
-
- node = g_hash_table_lookup(root->children, allow_override_key);
- if (node != NULL) {
- gboolean allow_override;
-
- allow_override = (g_strcmp0(node->content, "true") == 0);
- g_object_set(G_OBJECT(display),
- "allow-override", allow_override,
- NULL);
- }
-
- node = g_hash_table_lookup(root->children, certificate_key);
- if (node != NULL) {
- const char *subject_key = g_intern_string("subject");
- node = g_hash_table_lookup(node->children, subject_key);
- if (node != NULL) {
- g_object_set(G_OBJECT(display),
- "host-subject", node->content,
- NULL);
- }
- }
-
- node = g_hash_table_lookup(root->children, proxy_key);
- if (node != NULL) {
- g_object_set(G_OBJECT(display), "proxy-url", node->content, NULL);
- }
-
/* FIXME: this overrides the ticket/expiry which may
* already be set
*/
--
2.14.4

265
SOURCES/0039-vm-display-Move-XML-parsing-from-ovirt-vm-xml.c-file.patch

@ -0,0 +1,265 @@ @@ -0,0 +1,265 @@
From c81f18b9dd4888145ac979addb4ef5d73585a176 Mon Sep 17 00:00:00 2001
From: "Eduardo Lima (Etrunko)" <etrunko@redhat.com>
Date: Tue, 19 Sep 2017 12:02:32 -0300
Subject: [PATCH] vm-display: Move XML parsing from ovirt-vm-xml.c file

Following the model of other resources, the code for parsing the XML
elements for the OvirtVmDisplay object where it really belongs to.

Signed-off-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
---
govirt/Makefile.am | 1 -
govirt/ovirt-vm-display.c | 60 +++++++++++++++++++++++++++++
govirt/ovirt-vm-display.h | 2 +
govirt/ovirt-vm-xml.c | 96 -----------------------------------------------
govirt/ovirt-vm.c | 15 ++++++--
5 files changed, 74 insertions(+), 100 deletions(-)
delete mode 100644 govirt/ovirt-vm-xml.c

diff --git a/govirt/Makefile.am b/govirt/Makefile.am
index 9bf0eba..1a59f2c 100644
--- a/govirt/Makefile.am
+++ b/govirt/Makefile.am
@@ -73,7 +73,6 @@ libgovirt_la_SOURCES = \
ovirt-utils.c \
ovirt-vm.c \
ovirt-vm-display.c \
- ovirt-vm-xml.c \
ovirt-vm-pool.c \
$(NULL)

diff --git a/govirt/ovirt-vm-display.c b/govirt/ovirt-vm-display.c
index b03c303..ebb04c2 100644
--- a/govirt/ovirt-vm-display.c
+++ b/govirt/ovirt-vm-display.c
@@ -24,6 +24,7 @@

#include "ovirt-enum-types.h"
#include "ovirt-vm-display.h"
+#include "ovirt-utils.h"

#define OVIRT_VM_DISPLAY_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE((obj), OVIRT_TYPE_VM_DISPLAY, OvirtVmDisplayPrivate))
@@ -303,3 +304,62 @@ OvirtVmDisplay *ovirt_vm_display_new(void)
{
return OVIRT_VM_DISPLAY(g_object_new(OVIRT_TYPE_VM_DISPLAY, NULL));
}
+
+static gboolean ovirt_vm_display_set_from_xml(OvirtVmDisplay *display, RestXmlNode *node)
+{
+ OvirtVmDisplayType type;
+ OvirtXmlElement display_elements[] = {
+ { .prop_name = "type",
+ .xml_path = "type",
+ },
+ { .prop_name = "address",
+ .xml_path = "address",
+ },
+ { .prop_name = "port",
+ .xml_path = "port",
+ },
+ { .prop_name = "secure-port",
+ .xml_path = "secure_port",
+ },
+ { .prop_name = "monitor-count",
+ .xml_path = "monitors",
+ },
+ { .prop_name = "smartcard",
+ .xml_path = "smartcard_enabled",
+ },
+ { .prop_name = "allow-override",
+ .xml_path = "allow_override",
+ },
+ { .prop_name = "host-subject",
+ .xml_path = "certificate/subject",
+ },
+ { .prop_name = "proxy-url",
+ .xml_path = "proxy",
+ },
+ { NULL, },
+ };
+
+ ovirt_rest_xml_node_parse(node, G_OBJECT(display), display_elements);
+ g_object_get(G_OBJECT(display), "type", &type, NULL);
+ if (type == OVIRT_VM_DISPLAY_INVALID) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+OvirtVmDisplay *ovirt_vm_display_new_from_xml(RestXmlNode *node)
+{
+ OvirtVmDisplay *display;
+
+ g_return_val_if_fail(node != NULL, NULL);
+
+ display = ovirt_vm_display_new();
+
+ if (!ovirt_vm_display_set_from_xml(display, node)) {
+ g_object_unref(display);
+ return NULL;
+ }
+
+ return display;
+}
diff --git a/govirt/ovirt-vm-display.h b/govirt/ovirt-vm-display.h
index 38ef9b7..11a5074 100644
--- a/govirt/ovirt-vm-display.h
+++ b/govirt/ovirt-vm-display.h
@@ -24,6 +24,7 @@

#include <glib-object.h>
#include <govirt/ovirt-types.h>
+#include <rest/rest-xml-node.h>

G_BEGIN_DECLS

@@ -61,6 +62,7 @@ typedef enum {

GType ovirt_vm_display_get_type(void);
OvirtVmDisplay *ovirt_vm_display_new(void);
+OvirtVmDisplay *ovirt_vm_display_new_from_xml(RestXmlNode *node);

G_END_DECLS

diff --git a/govirt/ovirt-vm-xml.c b/govirt/ovirt-vm-xml.c
deleted file mode 100644
index 0603427..0000000
--- a/govirt/ovirt-vm-xml.c
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * ovirt-vm-xml.c
- *
- * Copyright (C) 2011, 2013 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see
- * <http://www.gnu.org/licenses/>.
- *
- * Author: Christophe Fergeau <cfergeau@redhat.com>
- */
-#include <config.h>
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "ovirt-enum-types.h"
-#include "ovirt-utils.h"
-#include "ovirt-vm.h"
-#include "ovirt-vm-display.h"
-#include "ovirt-vm-private.h"
-
-static gboolean vm_set_display_from_xml(OvirtVm *vm,
- RestXmlNode *root)
-{
- OvirtVmDisplay *display;
- OvirtVmDisplayType type;
- OvirtXmlElement display_elements[] = {
- { .prop_name = "type",
- .xml_path = "type",
- },
- { .prop_name = "address",
- .xml_path = "address",
- },
- { .prop_name = "port",
- .xml_path = "port",
- },
- { .prop_name = "secure-port",
- .xml_path = "secure_port",
- },
- { .prop_name = "monitor-count",
- .xml_path = "monitors",
- },
- { .prop_name = "smartcard",
- .xml_path = "smartcard_enabled",
- },
- { .prop_name = "allow-override",
- .xml_path = "allow_override",
- },
- { .prop_name = "host-subject",
- .xml_path = "certificate/subject",
- },
- { .prop_name = "proxy-url",
- .xml_path = "proxy",
- },
- { NULL, },
- };
-
- if (root == NULL) {
- return FALSE;
- }
- root = rest_xml_node_find(root, "display");
- if (root == NULL) {
- g_debug("Could not find 'display' node");
- return FALSE;
- }
- display = ovirt_vm_display_new();
- ovirt_rest_xml_node_parse(root, G_OBJECT(display), display_elements);
- g_object_get(G_OBJECT(display), "type", &type, NULL);
- if (type == OVIRT_VM_DISPLAY_INVALID) {
- return FALSE;
- }
-
- /* FIXME: this overrides the ticket/expiry which may
- * already be set
- */
- g_object_set(G_OBJECT(vm), "display", display, NULL);
- g_object_unref(G_OBJECT(display));
-
- return TRUE;
-}
-
-G_GNUC_INTERNAL gboolean ovirt_vm_refresh_from_xml(OvirtVm *vm, RestXmlNode *node)
-{
- return vm_set_display_from_xml(vm, node);
-}
diff --git a/govirt/ovirt-vm.c b/govirt/ovirt-vm.c
index f30022d..95c1e4d 100644
--- a/govirt/ovirt-vm.c
+++ b/govirt/ovirt-vm.c
@@ -180,7 +180,8 @@ static gboolean ovirt_vm_init_from_xml(OvirtResource *resource,
RestXmlNode *node,
GError **error)
{
- gboolean parsed_ok;
+ OvirtVmDisplay *display;
+ RestXmlNode *display_node;
OvirtResourceClass *parent_class;
OvirtXmlElement vm_elements[] = {
{ .prop_name = "host-href",
@@ -205,11 +206,19 @@ static gboolean ovirt_vm_init_from_xml(OvirtResource *resource,
{ NULL, },
};

- parsed_ok = ovirt_vm_refresh_from_xml(OVIRT_VM(resource), node);
- if (!parsed_ok) {
+ display_node = rest_xml_node_find(node, "display");
+ if (display_node == NULL) {
+ g_debug("Could not find 'display' node");
return FALSE;
}

+ display = ovirt_vm_display_new_from_xml(display_node);
+ if (display == NULL)
+ return FALSE;
+
+ g_object_set(G_OBJECT(resource), "display", display, NULL);
+ g_object_unref(G_OBJECT(display));
+
if (!ovirt_rest_xml_node_parse(node, G_OBJECT(resource), vm_elements))
return FALSE;

--
2.14.4

97
SOURCES/0040-vm-Set-ticket-expiry-using-OvirtXmlElement-struct.patch

@ -0,0 +1,97 @@ @@ -0,0 +1,97 @@
From 3a92d61ba92b85c0d31aa836713344085dab813e Mon Sep 17 00:00:00 2001
From: "Eduardo Lima (Etrunko)" <etrunko@redhat.com>
Date: Wed, 10 May 2017 15:16:27 -0300
Subject: [PATCH] vm: Set 'ticket/expiry' using OvirtXmlElement struct

Signed-off-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
---
govirt/ovirt-vm.c | 56 +++++++++++++++++++++++++++++++------------------------
1 file changed, 32 insertions(+), 24 deletions(-)

diff --git a/govirt/ovirt-vm.c b/govirt/ovirt-vm.c
index 95c1e4d..8cd482b 100644
--- a/govirt/ovirt-vm.c
+++ b/govirt/ovirt-vm.c
@@ -381,48 +381,56 @@ gboolean ovirt_vm_stop(OvirtVm *vm, OvirtProxy *proxy, GError **error)

static gboolean parse_ticket_status(RestXmlNode *root, OvirtResource *resource, GError **error)
{
- OvirtVm *vm;
- RestXmlNode *node;
- const char *ticket_key = g_intern_string("ticket");
- const char *value_key = g_intern_string("value");
- const char *expiry_key = g_intern_string("expiry");
OvirtVmDisplay *display;
+ gchar *ticket = NULL;
+ guint expiry = 0;
+ gboolean ret = FALSE;
+ OvirtXmlElement ticket_elements[] = {
+ { .prop_name = "ticket",
+ .xml_path = "value",
+ },
+ { .prop_name = "expiry",
+ .xml_path = "expiry",
+ },
+ { NULL, },
+ };

g_return_val_if_fail(root != NULL, FALSE);
g_return_val_if_fail(OVIRT_IS_VM(resource), FALSE);
g_return_val_if_fail(error == NULL || *error == NULL, FALSE);

- vm = OVIRT_VM(resource);
- root = g_hash_table_lookup(root->children, ticket_key);
+ g_object_get(G_OBJECT(resource), "display", &display, NULL);
+ g_return_val_if_fail(display != NULL, FALSE);
+
+ root = rest_xml_node_find(root, "ticket");
if (root == NULL) {
g_set_error(error, OVIRT_ERROR, OVIRT_ERROR_PARSING_FAILED,
_("Could not find 'ticket' node"));
- g_return_val_if_reached(FALSE);
+ goto end;
}
- node = g_hash_table_lookup(root->children, value_key);
- if (node == NULL) {
+
+ ovirt_rest_xml_node_parse(root, G_OBJECT(display), ticket_elements);
+
+ g_object_get(G_OBJECT(display), "ticket", &ticket, "expiry", &expiry, NULL);
+
+ if (ticket == NULL) {
g_set_error(error, OVIRT_ERROR, OVIRT_ERROR_PARSING_FAILED,
_("Could not find 'value' node"));
- g_return_val_if_reached(FALSE);
+ goto end;
}
+ g_free(ticket);

- g_object_get(G_OBJECT(vm), "display", &display, NULL);
- g_return_val_if_fail(display != NULL, FALSE);
- g_object_set(G_OBJECT(display), "ticket", node->content, NULL);
-
- node = g_hash_table_lookup(root->children, expiry_key);
- if (node == NULL) {
+ if (expiry == 0) {
g_set_error(error, OVIRT_ERROR, OVIRT_ERROR_PARSING_FAILED,
_("Could not find 'expiry' node"));
- g_object_unref(G_OBJECT(display));
- g_return_val_if_reached(FALSE);
+ goto end;
}
- g_object_set(G_OBJECT(display),
- "expiry", strtoul(node->content, NULL, 0),
- NULL);
+
+ ret = TRUE;
+
+end:
g_object_unref(G_OBJECT(display));
-
- return TRUE;
+ return ret;
}


--
2.14.4

38
SOURCES/0041-test-govirt-Add-display-node-to-vm-XMLs.patch

@ -0,0 +1,38 @@ @@ -0,0 +1,38 @@
From a2abf332bf99baf1d6b6a96d9153b44efdedf384 Mon Sep 17 00:00:00 2001
From: "Eduardo Lima (Etrunko)" <etrunko@redhat.com>
Date: Fri, 22 Jun 2018 18:18:53 -0300
Subject: [PATCH] test-govirt: Add 'display' node to vm XMLs

Makes 'make distcheck' pass again. Test-govirt was failing since commit
039c8d8, because the 'display' node is mandatory, but the return value
of the function vm_set_display_from_xml() had been ignored.

Signed-off-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
---
tests/test-govirt.c | 8 ++++++++
1 file changed, 8 insertions(+)

diff --git a/tests/test-govirt.c b/tests/test-govirt.c
index 247a27a..7f2cd57 100644
--- a/tests/test-govirt.c
+++ b/tests/test-govirt.c
@@ -194,9 +194,17 @@ static void test_govirt_list_duplicate_vms(void)
const char *vms_body = "<vms> \
<vm href=\"api/vms/uuid0\" id=\"uuid0\"> \
<name>vm0</name> \
+ <display> \
+ <type>spice</type> \
+ <monitors>1</monitors> \
+ </display> \
</vm> \
<vm href=\"api/vms/uuid1\" id=\"uuid1\"> \
<name>vm0</name> \
+ <display> \
+ <type>spice</type> \
+ <monitors>1</monitors> \
+ </display> \
</vm> \
</vms>";

--
2.14.4

65
SOURCES/0042-proxy-Set-detailed-error-message-for-async-call.patch

@ -0,0 +1,65 @@ @@ -0,0 +1,65 @@
From 01563a00550dd001f080aeddd8c6bbc35c676991 Mon Sep 17 00:00:00 2001
From: "Eduardo Lima (Etrunko)" <etrunko@redhat.com>
Date: Wed, 11 Jul 2018 15:42:16 -0300
Subject: [PATCH] proxy: Set detailed error message for async call

The rest API returns more detailed error messages with the result, not
only the literal corresponding to the value. If this is the case, we set
a new error message and return it.

For example, before this change, virt-viewer showed a dialog with a
vague 'Bad Request' message, and now a much more detailed 'Operation
Failed: query execution failed due to insufficient permissions.'

Signed-off-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
---
govirt/ovirt-proxy.c | 20 ++++++++++++++++++--
1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/govirt/ovirt-proxy.c b/govirt/ovirt-proxy.c
index 921e22e..f8e629e 100644
--- a/govirt/ovirt-proxy.c
+++ b/govirt/ovirt-proxy.c
@@ -240,6 +240,22 @@ call_async_cancelled_cb (G_GNUC_UNUSED GCancellable *cancellable,
}


+static void rest_call_async_set_error(RestProxyCall *call, GSimpleAsyncResult *result, const GError *error)
+{
+ GError *local_error = NULL;
+ RestXmlNode *root = ovirt_rest_xml_node_from_call(call);
+
+ if (root != NULL && ovirt_utils_gerror_from_xml_fault(root, &local_error)) {
+ g_debug("ovirt_rest_call_async(): %s", local_error->message);
+ g_simple_async_result_set_from_error(result, local_error);
+ g_clear_error(&local_error);
+ } else {
+ g_simple_async_result_set_from_error(result, error);
+ }
+
+ rest_xml_node_unref(root);
+}
+
static void
call_async_cb(RestProxyCall *call, const GError *error,
G_GNUC_UNUSED GObject *weak_object,
@@ -249,7 +265,7 @@ call_async_cb(RestProxyCall *call, const GError *error,
GSimpleAsyncResult *result = data->result;

if (error != NULL) {
- g_simple_async_result_set_from_error(result, error);
+ rest_call_async_set_error(call, result, error);
} else {
GError *call_error = NULL;
gboolean callback_result = TRUE;
@@ -259,7 +275,7 @@ call_async_cb(RestProxyCall *call, const GError *error,
data->call_user_data,
&call_error);
if (call_error != NULL) {
- g_simple_async_result_set_from_error(result, call_error);
+ rest_call_async_set_error(call, result, call_error);
}
}

--
2.20.1

107
SOURCES/0043-cdrom-Set-file-property-using-OvirtXmlElement-struct.patch

@ -0,0 +1,107 @@ @@ -0,0 +1,107 @@
From 53fb63d610503679bd3f4e2780989076544ddb14 Mon Sep 17 00:00:00 2001
From: "Eduardo Lima (Etrunko)" <etrunko@redhat.com>
Date: Thu, 4 May 2017 15:54:02 -0300
Subject: [PATCH] cdrom: Set file property using OvirtXmlElement struct

This was the last place left to move to the new automatic parsing
scheme.

Signed-off-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
---
govirt/ovirt-cdrom.c | 57 +++++++++++++++++---------------------------
1 file changed, 22 insertions(+), 35 deletions(-)

diff --git a/govirt/ovirt-cdrom.c b/govirt/ovirt-cdrom.c
index d852403..5bab7d3 100644
--- a/govirt/ovirt-cdrom.c
+++ b/govirt/ovirt-cdrom.c
@@ -28,6 +28,7 @@
#include "ovirt-proxy-private.h"
#include "ovirt-resource-private.h"
#include "ovirt-resource-rest-call.h"
+#include "ovirt-utils.h"

#define OVIRT_CDROM_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE((obj), OVIRT_TYPE_CDROM, OvirtCdromPrivate))
@@ -95,25 +96,29 @@ static void ovirt_cdrom_finalize(GObject *object)
}


-static gboolean ovirt_cdrom_refresh_from_xml(OvirtCdrom *cdrom,
- RestXmlNode *node)
+static gboolean ovirt_cdrom_init_from_xml(OvirtResource *resource,
+ RestXmlNode *node,
+ GError **error)
{
- RestXmlNode *file_node;
- const char *file;
- const char *file_key = g_intern_string("file");
+ gboolean ret = FALSE;
char *name;
+ OvirtResourceClass *parent_class;
+ OvirtXmlElement cdrom_elements[] = {
+ { .prop_name = "file",
+ .xml_path = "file",
+ .xml_attr = "id",
+ },
+ { NULL , },
+ };

- file_node = g_hash_table_lookup(node->children, file_key);
- if (file_node != NULL) {
- file = rest_xml_node_get_attr(file_node, "id");
- if (g_strcmp0(file, cdrom->priv->file) != 0) {
- g_free(cdrom->priv->file);
- cdrom->priv->file = g_strdup(file);
- g_object_notify(G_OBJECT(cdrom), "file");
- }
- }
+ parent_class = OVIRT_RESOURCE_CLASS(ovirt_cdrom_parent_class);
+
+ if (!parent_class->init_from_xml(resource, node, error))
+ return FALSE;

- g_object_get(G_OBJECT(cdrom), "name", &name, NULL);
+ ovirt_rest_xml_node_parse(node, G_OBJECT(resource), cdrom_elements);
+
+ g_object_get(G_OBJECT(resource), "name", &name, NULL);
if (name == NULL) {
/* Build up fake name as ovirt_collection_refresh_from_xml()
* expects it to be set (it uses it as a hash table key), but
@@ -122,32 +127,14 @@ static gboolean ovirt_cdrom_refresh_from_xml(OvirtCdrom *cdrom,
* enough for now
*/
g_debug("Setting fake 'name' for cdrom resource");
- g_object_set(G_OBJECT(cdrom), "name", "cdrom0", NULL);
- } else {
- g_free(name);
+ g_object_set(G_OBJECT(resource), "name", "cdrom0", NULL);
}

+ g_free(name);
return TRUE;
}


-static gboolean ovirt_cdrom_init_from_xml(OvirtResource *resource,
- RestXmlNode *node,
- GError **error)
-{
- gboolean parsed_ok;
- OvirtResourceClass *parent_class;
-
- parsed_ok = ovirt_cdrom_refresh_from_xml(OVIRT_CDROM(resource), node);
- if (!parsed_ok) {
- return FALSE;
- }
- parent_class = OVIRT_RESOURCE_CLASS(ovirt_cdrom_parent_class);
-
- return parent_class->init_from_xml(resource, node, error);
-}
-
-
static char *ovirt_cdrom_to_xml(OvirtResource *resource)
{
OvirtCdrom *cdrom;
--
2.20.1

30
SOURCES/0044-proxy-Don-t-try-to-unref-NULL-root-node.patch

@ -0,0 +1,30 @@ @@ -0,0 +1,30 @@
From 8032575cbe274c9e70ec2a0efb0b536f13dbc6cd Mon Sep 17 00:00:00 2001
From: Christophe Fergeau <cfergeau@redhat.com>
Date: Fri, 21 Dec 2018 13:15:16 +0100
Subject: [PATCH] proxy: Don't try to unref NULL root node

When an error occurs, we may have failed to get any data, so 'root' may
be NULL. Trying to unref it triggers a critical. This happens for
example when trying to connect to a remote host with an invalid
certificate.
---
govirt/ovirt-proxy.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/govirt/ovirt-proxy.c b/govirt/ovirt-proxy.c
index f8e629e..920ef21 100644
--- a/govirt/ovirt-proxy.c
+++ b/govirt/ovirt-proxy.c
@@ -253,7 +253,9 @@ static void rest_call_async_set_error(RestProxyCall *call, GSimpleAsyncResult *r
g_simple_async_result_set_from_error(result, error);
}

- rest_xml_node_unref(root);
+ if (root != NULL) {
+ rest_xml_node_unref(root);
+ }
}

static void
--
2.20.1

97
SOURCES/0045-utils-Check-for-valid-data-before-calling-rest_xml_p.patch

@ -0,0 +1,97 @@ @@ -0,0 +1,97 @@
From d6ddeff795ce3f132f1e266fc813e0a4917f8bf7 Mon Sep 17 00:00:00 2001
From: "Eduardo Lima (Etrunko)" <etrunko@redhat.com>
Date: Mon, 4 Feb 2019 15:58:40 -0200
Subject: [PATCH] utils: Check for valid data before calling
rest_xml_parser_parse_from_data()

In the case of HTTP errors, such as a invalid TLS certificate, the
returned data is NULL, and the code in librest does not check for the
pointer being valid, causing a segfault.

The users of this function have been updated to check for NULL return
value.

Signed-off-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
---
govirt/ovirt-proxy.c | 6 ++++++
govirt/ovirt-resource.c | 9 ++++++++-
govirt/ovirt-utils.c | 7 +++++--
3 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/govirt/ovirt-proxy.c b/govirt/ovirt-proxy.c
index 920ef21..9cdd211 100644
--- a/govirt/ovirt-proxy.c
+++ b/govirt/ovirt-proxy.c
@@ -365,6 +365,11 @@ static gboolean get_collection_xml_async_cb(OvirtProxy* proxy,
data = (OvirtProxyGetCollectionAsyncData *)user_data;

root = ovirt_rest_xml_node_from_call(call);
+ if (root == NULL) {
+ g_set_error_literal(error, OVIRT_ERROR, OVIRT_ERROR_PARSING_FAILED,
+ _("Failed to parse response from collection"));
+ goto end;
+ }

/* Do the parsing */
g_warn_if_fail(data->parser != NULL);
@@ -374,6 +379,7 @@ static gboolean get_collection_xml_async_cb(OvirtProxy* proxy,

rest_xml_node_unref(root);

+end:
return parsed;
}

diff --git a/govirt/ovirt-resource.c b/govirt/ovirt-resource.c
index 1984b1d..936e912 100644
--- a/govirt/ovirt-resource.c
+++ b/govirt/ovirt-resource.c
@@ -868,17 +868,24 @@ static gboolean ovirt_resource_refresh_async_cb(OvirtProxy *proxy,
{
OvirtResource *resource;
RestXmlNode *root;
- gboolean refreshed;
+ gboolean refreshed = FALSE;

g_return_val_if_fail(REST_IS_PROXY_CALL(call), FALSE);
g_return_val_if_fail(OVIRT_IS_RESOURCE(user_data), FALSE);

root = ovirt_rest_xml_node_from_call(call);
+ if (root == NULL) {
+ g_set_error_literal(error, OVIRT_ERROR, OVIRT_ERROR_PARSING_FAILED,
+ _("Failed to parse response from resource"));
+ goto end;
+ }
+
resource = OVIRT_RESOURCE(user_data);
refreshed = ovirt_resource_init_from_xml(resource, root, error);

rest_xml_node_unref(root);

+end:
return refreshed;
}

diff --git a/govirt/ovirt-utils.c b/govirt/ovirt-utils.c
index dfaf09d..56ce2e1 100644
--- a/govirt/ovirt-utils.c
+++ b/govirt/ovirt-utils.c
@@ -40,11 +40,14 @@ ovirt_rest_xml_node_from_call(RestProxyCall *call)
{
RestXmlParser *parser;
RestXmlNode *node;
+ const char * data = rest_proxy_call_get_payload (call);
+
+ if (data == NULL)
+ return NULL;

parser = rest_xml_parser_new ();

- node = rest_xml_parser_parse_from_data (parser,
- rest_proxy_call_get_payload (call),
+ node = rest_xml_parser_parse_from_data (parser, data,
rest_proxy_call_get_payload_length (call));

g_object_unref(G_OBJECT(parser));
--
2.20.1

146
SOURCES/0046-Update-tests-certificates.patch

@ -0,0 +1,146 @@ @@ -0,0 +1,146 @@
From d8b4c483d8e31525b1290115fbded054b4e8c3ab Mon Sep 17 00:00:00 2001
From: "Eduardo Lima (Etrunko)" <etrunko@redhat.com>
Date: Tue, 21 May 2019 14:30:50 -0300
Subject: [PATCH] Update tests certificates

As reference, use https://www.spice-space.org/spice-user-manual.html#_generating_self_signed_certificates
in order to create new certificates. This procedure should not be
necessary anymore, current date of expiration is set to Dec 31st 9999.

Signed-off-by: Eduardo Lima (Etrunko) <etrunko@redhat.com>
---
tests/https-cert/ca-cert.pem | 60 ++++++++++++++++----------------
tests/https-cert/server-cert.pem | 54 ++++++++++++++--------------
2 files changed, 57 insertions(+), 57 deletions(-)

diff --git a/tests/https-cert/ca-cert.pem b/tests/https-cert/ca-cert.pem
index 1f37f35..b904a2d 100644
--- a/tests/https-cert/ca-cert.pem
+++ b/tests/https-cert/ca-cert.pem
@@ -1,32 +1,32 @@
-----BEGIN CERTIFICATE-----
-MIIFfzCCA2egAwIBAgIJAJe68wcZuCytMA0GCSqGSIb3DQEBCwUAMFYxCzAJBgNV
-BAYTAlhYMRUwEwYDVQQHDAxEZWZhdWx0IENpdHkxHDAaBgNVBAoME0RlZmF1bHQg
-Q29tcGFueSBMdGQxEjAQBgNVBAMMCWdvdmlydCBDQTAeFw0xNjA0MTIxNTEyNDFa
-Fw0xOTA0MTIxNTEyNDFaMFYxCzAJBgNVBAYTAlhYMRUwEwYDVQQHDAxEZWZhdWx0
-IENpdHkxHDAaBgNVBAoME0RlZmF1bHQgQ29tcGFueSBMdGQxEjAQBgNVBAMMCWdv
-dmlydCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALj2s6YqG9CE
-O7ZxudxjGRSN3rUsnc++p0I+Exo32lsPMD3AXGJ9EwGnXhoRvGnuF2piICZ3CLl2
-nOH/7Ta8Sb/RuHj67XpJyOhgamM9HULff7ZFXyOrSVyf7YhetCqtx6QhwGfeJ88A
-MsClJmLZ0AkC1rqtIze9r7HCHZCQxkZZHKV0EhF8RaK0oBxjt6MFIru/kzQCXvWT
-t9/RaaxhOdboCtTEmu5oTBQfmKUzl4KT3byYVhdm70MEu/PES1XcgnI2RiHcggrI
-jJ7IknDZTZVK6r0uYLwhBLYA7WsHjRuinTC45dfGcZo0ZTn3khO2Get1negU6wuq
-kkxyc/Su+tU+eH74haW58Xa3DRXlRNHu91ll81W1Wtpi2osDlImIbM/a+FTSTenl
-/bIpPOSqbncvi0yfOoZJhH/u8jgQl3hKVgcA8wYdBj/zcHknldnjeS/k0zI84jOd
-ZrSWL/U7CRGiqJJgRpEKMlggf8Zyh+Lu5Hs6DJrSMG36nbLuukioNCzk7mzMJtOk
-kcE2576RA/1qkYdno06ZHCR7AnOlwvOKusS8ApIti/quQy1COanBYKaiXOJOemZ2
-n5D3cDsqRk1s/Wj53Ci9KurhGoQOoquRXHv7Z3vzBtZdqZBdwLH3r0pM85a//M6c
-HkDwEDsZNUPlvteDahhMPt2qjJNI1ucVAgMBAAGjUDBOMB0GA1UdDgQWBBTxTMG0
-4azCV/NN7/DhFI5tVp9t3TAfBgNVHSMEGDAWgBTxTMG04azCV/NN7/DhFI5tVp9t
-3TAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4ICAQA0OOkImczWNwgz/CaB
-mEx6odCM0Kv2ozZ6d8ttsj4w9S3tn0HSR1xM62F/GmO1NfxQXKWTR3xYMou0fQVA
-RskWy/I9WVN/BTD2QSPD9b3fqZvXgi5eMXVeT/1zO2LywV/APLzVl+jbB3WT9J+9
-1CHyiMNQUUbkIULmE3Z4FPYL30TGbAj4QSIIAbJlHAxRsrTbLXqRXnqw/NxdKdBk
-v1AOvCenu1HcbtWwDnwrIJGt8/igPB5KqsBzHVfcVmvpXUDC1oLf8w8v7nUB55hs
-ZMFyaeEcmc+W2B/JM26npbfTCjST9D6kxBXUhIeu9oJDimfiUqYUaZOuybUM6ZEy
-76vsO8qB06AuA+KhbvBgz8VHveMCnL516VIB8gxThvBgGIe7AQJuDHCy3+oRJ1+k
-kQm04t2k+Gg03ZpgtzbKaOCL6zRFyy5XE8h59/92KyUh804WTiS5MQZLTnqONqS1
-49BWXgTZgL+PvMr2xzE5ECs3lkcNpO3TvQJB6eSg0X6NQEscQRbTI1qrmszfAov3
-teQQlwZZHwzXhJxDNAW9u4oaCWbhRsVbYIoDDdvgIeeLozNaQgJkVzQOrSDOcbrk
-4cclYBgxgSAp1wvlje6iUFGGz6Q37GLBhqBTONjIL2ArlizqznGvBbQ/0CO1bij4
-mePFkPdR8OZWT1+FN6HavKYtPg==
+MIIFjzCCA3egAwIBAgIUI09vQ7noXtQvCMMLivExKvahRI8wDQYJKoZIhvcNAQEL
+BQAwVjELMAkGA1UEBhMCWFgxFTATBgNVBAcMDERlZmF1bHQgQ2l0eTEcMBoGA1UE
+CgwTRGVmYXVsdCBDb21wYW55IEx0ZDESMBAGA1UEAwwJbG9jYWxob3N0MCAXDTE5
+MDUyMTE3MjUwN1oYDzk5OTkxMjMxMTcyNTA3WjBWMQswCQYDVQQGEwJYWDEVMBMG
+A1UEBwwMRGVmYXVsdCBDaXR5MRwwGgYDVQQKDBNEZWZhdWx0IENvbXBhbnkgTHRk
+MRIwEAYDVQQDDAlsb2NhbGhvc3QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
+AoICAQC49rOmKhvQhDu2cbncYxkUjd61LJ3PvqdCPhMaN9pbDzA9wFxifRMBp14a
+Ebxp7hdqYiAmdwi5dpzh/+02vEm/0bh4+u16ScjoYGpjPR1C33+2RV8jq0lcn+2I
+XrQqrcekIcBn3ifPADLApSZi2dAJAta6rSM3va+xwh2QkMZGWRyldBIRfEWitKAc
+Y7ejBSK7v5M0Al71k7ff0WmsYTnW6ArUxJruaEwUH5ilM5eCk928mFYXZu9DBLvz
+xEtV3IJyNkYh3IIKyIyeyJJw2U2VSuq9LmC8IQS2AO1rB40bop0wuOXXxnGaNGU5
+95ITthnrdZ3oFOsLqpJMcnP0rvrVPnh++IWlufF2tw0V5UTR7vdZZfNVtVraYtqL
+A5SJiGzP2vhU0k3p5f2yKTzkqm53L4tMnzqGSYR/7vI4EJd4SlYHAPMGHQY/83B5
+J5XZ43kv5NMyPOIznWa0li/1OwkRoqiSYEaRCjJYIH/Gcofi7uR7Ogya0jBt+p2y
+7rpIqDQs5O5szCbTpJHBNue+kQP9apGHZ6NOmRwkewJzpcLzirrEvAKSLYv6rkMt
+QjmpwWCmolziTnpmdp+Q93A7KkZNbP1o+dwovSrq4RqEDqKrkVx7+2d78wbWXamQ
+XcCx969KTPOWv/zOnB5A8BA7GTVD5b7Xg2oYTD7dqoyTSNbnFQIDAQABo1MwUTAd
+BgNVHQ4EFgQU8UzBtOGswlfzTe/w4RSObVafbd0wHwYDVR0jBBgwFoAU8UzBtOGs
+wlfzTe/w4RSObVafbd0wDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOC
+AgEAUFRLaj6YtYRLG+PAT9ic+VEqX2qxttBO2/LpjFwpsBPuNs6/kHF6VNPOhV6K
+6SM4yfWM+y37IqQATTCe4eMiMEun+4DMzhkKX4Lbz+FR/n7xyibwNALZH/M0P6gt
+nXIciyLcG7hmFkgQCGBCVyavrh6q7HcE14MYZlCCt+0rRyJu+PEd4sbcnwo+Ia9p
+4tEeTK8cU5Ek4kJh/AkdlabgGQ/Cq24Y0+Tfix/0i3tRPM1jWgaukKlD2wPh/Idp
+KjtPqx1PM0MSgCoalNxcCAOHPh1h/8NJt+yIDwurOd+XEbG+tBnLE8y0upyO5w1U
+SU9XCBqv7fQnSPOBgvQ/5OwribIHLuvjCVF0BkI3u+NeNVSzFtGreFHNWJ6foA6o
+Um50pw/hCgLptOfhXYkCx2uP7XxOhjlpJOc+1I05Y44vai5YmpqwvvEWkcV2Dlw3
+ihIHWca6wxVql61LqIzqoiVxNhGiOGTPWbyGMBWA+8cbxVqG0zBKl3A4vox0cGRX
+QPBIiUFjhx4Z5pYZuJ5ndQHiclnYtEfC6+UppL08yrDdIzyLMxIpDqkUAw03TKKC
+TzCsa3DL10LTIulDJurC5SHgY+SrBrWAGuSy97Lmp0cogSBgU9VFqESKaB1lgtET
+c8dkOFwHdOIXu3iI9uKGcwkUfrjGsUdYOUJaAJ5t36WCw/Q=
-----END CERTIFICATE-----
diff --git a/tests/https-cert/server-cert.pem b/tests/https-cert/server-cert.pem
index 709369f..9ca912d 100644
--- a/tests/https-cert/server-cert.pem
+++ b/tests/https-cert/server-cert.pem
@@ -1,30 +1,30 @@
-----BEGIN CERTIFICATE-----
-MIIFIDCCAwgCAQEwDQYJKoZIhvcNAQELBQAwVjELMAkGA1UEBhMCWFgxFTATBgNV
+MIIFIjCCAwoCAQEwDQYJKoZIhvcNAQELBQAwVjELMAkGA1UEBhMCWFgxFTATBgNV
BAcMDERlZmF1bHQgQ2l0eTEcMBoGA1UECgwTRGVmYXVsdCBDb21wYW55IEx0ZDES
-MBAGA1UEAwwJZ292aXJ0IENBMB4XDTE2MDQxMjE1MTMzNVoXDTE5MDQxMjE1MTMz
-NVowVjELMAkGA1UEBhMCWFgxFTATBgNVBAcMDERlZmF1bHQgQ2l0eTEcMBoGA1UE
-CgwTRGVmYXVsdCBDb21wYW55IEx0ZDESMBAGA1UEAwwJbG9jYWxob3N0MIICIjAN
-BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAt6OkS5HhwwFLJWDmuRSOYCXwQP6v
-OlToc7rHvK0+shkspUb1KYks3iEw9djLQdxf1E5k+oDlifDKAMgd/AxkJn8kZ4f1
-i3183gFdad+UlMFwCliReb3opdtalR6Bef1CDE91+wsN1S4OLXYlVY/EO/sV4Ydh
-khReJiSQzUS+s1T9Nxa57YiuhJ6KYhS5SKkoFDQ7OmyvXM4cSnqOy7h4xBg8fBv9
-jxI24DNsF1qPg3XVQg3FDmHLEdRTlOWzq39qxzHPrTcFCboS1EaKHIX5DwlNR/L+
-x/JVqP99t2d/7lp2u8rveHsV0sLCoGK6ehbL6CHMXZQmmRQaVL/xueVIUvUhpwCS
-BXdxRNHpSizPkM4P7/0isgvJ8okElwKv2G46rJjt/AuQTOXVJDEfajHe/703E5r3
-iJkkG4Jd3uVeZIEigic9PEyervYk2VrWXIIZltfgaCUZYiJNRQ6xbG6RrKLYgSfV
-fpr8urFWFKs+j8dZHc8/GPi1tjTtaaYG0kXg3CGEh3Ww3ym0xjxrt2Qr62nMD+lH
-0loK8wdJbzsHgmLOGnURUWN55XKFpWcrP9rYHSl0d70u6YioMpIM2UClfRPQnLvX
-+/H3yBshAPQldBgseXJ9zlG1ho5fXaIg5u4mtNg+GccerNOFypdJJc97IdYFmyhm
-ww/6LcpMKk+e6wECAwEAATANBgkqhkiG9w0BAQsFAAOCAgEADePSnvlNHaO54TRl
-FZxfxNf/Ft3s+HP2ya6SC+tu1X7FgjbHQL4nm0Xf+pboAZoeUMujgUVGuYQ3ytkt
-irbSONYBbr439zZ4cPqWXqgzySTEiKwWR8REHXRPHJaupE09g+uEWo4E2u7423+k
-j3tbSkPZlObmsXkpdtQEw347yHcmZb8ujloxBopRK5KHchg/mXjiVGrkt9E8tzgX
-V8eG7CkCiEujnLpdjZ+7+AwmJoIuzB7xs2rXMe/zC7/4l2ViCFgjJKZra2oZLzqc
-FVBZXW8dAmWT4iIsZP4xXyzrKA8exzKgsdtXTMYNzgUsXH6Zcou0GhTR5jZvWbvZ
-Z0uPIXFnDRBqvK8nbRab0ok7iJRoLJhFih6q2tQwrpg05zPV39d9GLNwXKEKCo6/
-dqnqUhQcD5CpXoLhANbSgZZo7xdTM4Onxlm+h+3D/UxbciOQ8nRmNKUC+xX79+Xw
-zPLRULRs32brrfObOuOJuiA4tL81n9ghAdnbVhiZZvhxpJ/QvZWl4CH1UdR2/bO4
-+lkEAJDfLTP2uvWe0zYFS2E1WeJUOBjt6mU4sFNxqf5Vt+6PMWBGKvUg/JW+2kCP
-S5h1pRFDf8XOGWJ5UvzwlxP/VXrDo70xeY7Pdgk+TPr+TroJsNjorIi9Y0JXKZJ6
-dux12jowA6uKxtF7dmtA5szUKSU=
+MBAGA1UEAwwJbG9jYWxob3N0MCAXDTE5MDUyMTE3MjUzMloYDzk5OTkxMjMxMTcy
+NTMyWjBWMQswCQYDVQQGEwJYWDEVMBMGA1UEBwwMRGVmYXVsdCBDaXR5MRwwGgYD
+VQQKDBNEZWZhdWx0IENvbXBhbnkgTHRkMRIwEAYDVQQDDAlsb2NhbGhvc3QwggIi
+MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC3o6RLkeHDAUslYOa5FI5gJfBA
+/q86VOhzuse8rT6yGSylRvUpiSzeITD12MtB3F/UTmT6gOWJ8MoAyB38DGQmfyRn
+h/WLfXzeAV1p35SUwXAKWJF5veil21qVHoF5/UIMT3X7Cw3VLg4tdiVVj8Q7+xXh
+h2GSFF4mJJDNRL6zVP03FrntiK6EnopiFLlIqSgUNDs6bK9czhxKeo7LuHjEGDx8
+G/2PEjbgM2wXWo+DddVCDcUOYcsR1FOU5bOrf2rHMc+tNwUJuhLURoochfkPCU1H
+8v7H8lWo/323Z3/uWna7yu94exXSwsKgYrp6FsvoIcxdlCaZFBpUv/G55UhS9SGn
+AJIFd3FE0elKLM+Qzg/v/SKyC8nyiQSXAq/YbjqsmO38C5BM5dUkMR9qMd7/vTcT
+mveImSQbgl3e5V5kgSKCJz08TJ6u9iTZWtZcghmW1+BoJRliIk1FDrFsbpGsotiB
+J9V+mvy6sVYUqz6Px1kdzz8Y+LW2NO1ppgbSReDcIYSHdbDfKbTGPGu3ZCvracwP
+6UfSWgrzB0lvOweCYs4adRFRY3nlcoWlZys/2tgdKXR3vS7piKgykgzZQKV9E9Cc
+u9f78ffIGyEA9CV0GCx5cn3OUbWGjl9doiDm7ia02D4Zxx6s04XKl0klz3sh1gWb
+KGbDD/otykwqT57rAQIDAQABMA0GCSqGSIb3DQEBCwUAA4ICAQCdarzrfXWzSL1k
+MZ+D25teNSgZglXw7cpc/WVx2zQ26Wd7csig8Gac1vW/bQMk9XBbwZoI9tuHk62l
+6+9eXGgIgN5qUCchlqcO41IVSk4sWrvNPXiU7kbLrjmrh8txQM8D/YLKm8S8Muf7
+F4r/RhRkQY+85eOS2GEyj5AMnUlmi1g7wBkIiRipY4fMLowwX8ouQiJCvQE/LJYS
+rQlPDnvCwcVmOxEKUjQoZ0vKrD6zNrnWzEe3LXxQQI3OnnAqgVGHH7bQsY482apn
+2e+WRJouBSwOKEb27/DWMQoXaiVhNBh2wWt5xgKKupJB+PIyW0H2w0Gw1Jr2JY+I
+Lh5fXJXCB/BF3qsbJhi2mnNYWhPP4oOoLN/pT6m1FV/bbTEXlsxxczfE/zT4JRsi
+DhQRZ/FWhbpT9Z7I5kd76KjpKkRFi3Nkb9ezAW35xuo6Ex5x7EWNJM8FJuktNgIK
+Z7JxnqeC0DVEDSWhtxo6HTlx0HgpVTjRPKCVEt1d4itPRBMKueygul1se1jLlMw8
++8sRpCxdYU9KX18c+p4wANTke94vH5mrm2msK/oXmM77VDIGriEtr8tMIYZbGwKQ
+dhUKsH9eaReKHwoLqihQotpEi28DSng4EXSu9crZV/Yu7crL1+JBSF+N5OK7cf0q
+8K2k/Y/pshicpfHaEKDJmLp5vfULNw==
-----END CERTIFICATE-----
--
2.21.0

229
SPECS/libgovirt.spec

@ -0,0 +1,229 @@ @@ -0,0 +1,229 @@
# -*- rpm-spec -*-

%global with_gir 0

# Default to skipping autoreconf. Distros can change just this one line
# (or provide a command-line override) if they backport any patches that
# touch configure.ac or Makefile.am.

# Force running autoreconf because data center patches touch Makefile.am.
# To disable autoreconf, change the value to 0.
%{!?enable_autotools:%global enable_autotools 1}

%if 0%{?fedora} >= 15 || 0%{?rhel} >= 7
%global with_gir 1
%endif

Summary: A GObject library for interacting with oVirt REST API
Name: libgovirt
Version: 0.3.4
Release: 3%{?dist}%{?extra_release}
License: LGPLv2+
Group: Development/Libraries
Source: http://ftp.gnome.org/pub/GNOME/sources/libgovirt/0.3/%{name}-%{version}.tar.xz
URL: http://people.freedesktop.org/~teuf/govirt/
Patch01: 0001-proxy-Fix-persistent-session-with-oVirt-3.6.patch
Patch02: 0002-Force-use-of-v3-REST-API.patch
Patch03: 0003-New-storage-format-added-in-oVirt-4.1.patch
Patch04: 0004-proxy-Hold-reference-to-cancellable-object.patch
Patch05: 0005-proxy-Check-if-operation-is-cancelled-before-disconn.patch
Patch06: 0006-storage-domain-Factor-out-property-value-setting-fro.patch
Patch07: 0007-storage-domain-use-explicit-initialization-of-struct.patch
Patch08: 0008-storage-domain-Move-out-ovirt_resource_parse_xml-to-.patch
Patch09: 0009-utils-Remove-unused-function-ovirt_rest_xml_node_get.patch
Patch10: 0010-utils-Rename-ovirt_rest_xml_node_get_content_va-to-o.patch
Patch11: 0011-utils-Retrieve-node-attributes-in-ovirt_resource_par.patch
Patch12: 0012-utils-Support-G_TYPE_STRING-in-_set_property_value_f.patch
Patch13: 0013-utils-Support-G_TYPE_STRV-in-_set_property_value_fro.patch
Patch14: 0014-Introduce-auxiliary-function-ovirt_sub_collection_ne.patch
Patch15: 0015-New-API-functions-to-enable-search-queries-of-collec.patch
Patch16: 0016-Introduce-ovirt_resource_new-functions.patch
Patch17: 0017-Use-ovirt_resource_new-functions-instead-of-g_initab.patch
Patch18: 0018-Move-resource-type-definitions-to-ovirt-types.h.patch
Patch19: 0019-Initial-support-for-hosts.patch
Patch20: 0020-Initial-support-for-clusters.patch
Patch21: 0021-Initial-support-for-data-centers.patch
Patch22: 0022-vm-Introduce-ovirt_vm_get_host.patch
Patch23: 0023-vm-Introduce-ovirt_vm_get_cluster.patch
Patch24: 0024-host-Introduce-ovirt_host_get_cluster.patch
Patch25: 0025-cluster-Introduce-ovirt_cluster_get_data_center.patch
Patch26: 0026-storage-domain-Retrieve-data-center-ids.patch
Patch27: 0027-Add-missing-include-in-govirt.h.patch
Patch28: 0028-resource-Fix-ovirt_resource_rest_call_sync-return-va.patch
Patch29: 0029-resource-Fix-ovirt_resource_rest_call_sync-crash-on-.patch
Patch30: 0030-resource-Fix-ovirt_resource_init_from_xml_real-preco.patch
Patch31: 0031-resource-Update-xml-node-in-ovirt_resource_init_from.patch
Patch32: 0032-utils-Drop-type-member-from-OvirtXmlElement-struct.patch
Patch33: 0033-utils-Support-G_TYPE_UINT-in-_set_property_value_fro.patch
Patch34: 0034-utils-Improve-log-message-when-subnode-is-not-found.patch
Patch35: 0035-utils-Factor-out-basic-value-type-setting-from-_set_.patch
Patch36: 0036-utils-Get-enum-default-value-from-GParamSpec.patch
Patch37: 0037-vm-Set-vm-state-property-using-OvirtXmlElement-struc.patch
Patch38: 0038-vm-Set-values-of-OvirtVmDisplay-using-OvirtXmlElemen.patch
Patch39: 0039-vm-display-Move-XML-parsing-from-ovirt-vm-xml.c-file.patch
Patch40: 0040-vm-Set-ticket-expiry-using-OvirtXmlElement-struct.patch
Patch41: 0041-test-govirt-Add-display-node-to-vm-XMLs.patch
Patch42: 0042-proxy-Set-detailed-error-message-for-async-call.patch
Patch43: 0043-cdrom-Set-file-property-using-OvirtXmlElement-struct.patch
Patch44: 0044-proxy-Don-t-try-to-unref-NULL-root-node.patch
Patch45: 0045-utils-Check-for-valid-data-before-calling-rest_xml_p.patch
Patch46: 0046-Update-tests-certificates.patch

%if 0%{?enable_autotools}
BuildRequires: autoconf
BuildRequires: automake
BuildRequires: gettext-devel
BuildRequires: libtool
%endif

BuildRequires: pkgconfig(glib-2.0)
BuildRequires: rest-devel >= 0.7.92
# needed for make check to complete successfully
BuildRequires: dconf

BuildRequires: intltool
%if %{with_gir}
BuildRequires: gobject-introspection-devel
%endif

%description
libgovirt is a library that allows applications to use oVirt REST API
to list VMs managed by an oVirt instance, and to get the connection
parameters needed to make a SPICE/VNC connection to them.

%package devel
Summary: Libraries, includes, etc. to compile with the libgovirt library
Group: Development/Libraries
Requires: %{name}%{?_isa} = %{version}-%{release}
Requires: pkgconfig
Requires: glib2-devel

%description devel
libgovirt is a library that allows applications to use oVirt REST API
to list VMs managed by an oVirt instance, and to get the connection
parameters needed to make a SPICE/VNC connection to them.

Libraries, includes, etc. to compile with the libgovirt library

%prep
%autosetup -S git_am

%build
%if 0%{?enable_autotools}
autoreconf -if
%endif

%if %{with_gir}
%global gir_arg --enable-introspection=yes
%else
%global gir_arg --enable-introspection=no
%endif

%configure %{gir_arg}
%__make %{?_smp_mflags} V=1

%install
%__make install DESTDIR=%{buildroot}
rm -f %{buildroot}%{_libdir}/*.a
rm -f %{buildroot}%{_libdir}/*.la
%find_lang %{name} --with-gnome

%check
make check

%post -p /sbin/ldconfig

%postun -p /sbin/ldconfig

%files -f %{name}.lang
%doc AUTHORS COPYING MAINTAINERS README
%{_libdir}/%{name}.so.2*
%if %{with_gir}
%{_libdir}/girepository-1.0/GoVirt-1.0.typelib
%endif

%files devel
%{_libdir}/%{name}.so
%dir %{_includedir}/govirt-1.0/
%dir %{_includedir}/govirt-1.0/govirt/
%{_includedir}/govirt-1.0/govirt/*.h
%{_libdir}/pkgconfig/govirt-1.0.pc
%if %{with_gir}
%{_datadir}/gir-1.0/GoVirt-1.0.gir
%endif

%changelog
* Tue Apr 09 2019 Eduardo Lima (Etrunko) <etrunko@redhat.com> - 0.3.4-2
- Parse XML nodes automatically
Related: rhbz#1427467
- Set detailed error message for async call
Related: rhbz#1427467

* Fri Jun 08 2018 Christophe Fergeau <cfergeau@redhat.com> - 0.3.4-1
- Rebase to latest 0.3.4 upstream release. Still quite a few patches as
there was no 0.3.5 release yet
Resolves: rhbz#1584266

* Mon Oct 02 2017 Eduardo Lima (Etrunko) <etrunko@redhat.com> - 0.3.3-6
- Add support for Hosts, Clusters and Data Centers
Resolves: rhbz#1428401

* Mon Mar 13 2017 Eduardo Lima (Etrunko) <etrunko@redhat.com> - 0.3.3-5
- New storage format added in oVirt 4.1
Resolves: rhbz#1346215
- Check if operation was cancelled before disconnecting signal
Resolves: rhbz#1431275

* Fri Jul 01 2016 Christophe Fergeau <cfergeau@redhat.com> - 0.3.3-4
- Add upstream patch forcing use of the older v3 REST API as we don't support
yet the v4 API
Resolves: rhbz#1346215

* Tue Jun 14 2016 Christophe Fergeau <cfergeau@redhat.com> - 0.3.3-3
- Add upstream patch fixing unwanted authentication dialog for foreign menu
when using remote-viewer ovirt://
Resolves: rhbz#1346256

* Mon Jan 04 2016 Fabiano Fidêncio <fidencio@redhat.com> 0.3.3-2
- Fix crash when VM has several ISO domains
Resolves: rhbz#1274356
- Add OvirtProxy::sso-token support for oVirt 4.0
Resolves: rhbz#1324457

* Tue May 12 2015 Christophe Fergeau <cfergeau@redhat.com> 0.3.3-1
- Rebase to 0.3.3
Resolves: rhbz#1214234

* Fri Oct 10 2014 Christophe Fergeau <cfergeau@redhat.com> 0.3.1-3
- Add upstream patch allowing to remove CD images from an OvirtCdrom
Resolves: rhbz#1151171

* Tue Sep 30 2014 Christophe Fergeau <cfergeau@redhat.com> 0.3.1-2
- Requires a new enough librest as we use symbols not available in older
librest
Related: rhbz#1116844

* Mon Sep 08 2014 Christophe Fergeau <cfergeau@redhat.com> 0.3.1-1
- Rebase to libgovirt 0.3.1.
Resolves: rhbz#1116844

* Mon Jul 7 2014 Marc-Andre Lureau <marcandre.lureau@redhat.com> - 0.3.0-1
- Rebase to libgovirt 0.3.0.
Resolves: rhbz#1116844

* Fri Jan 24 2014 Daniel Mach <dmach@redhat.com> - 0.1.0-3
- Mass rebuild 2014-01-24

* Fri Dec 27 2013 Daniel Mach <dmach@redhat.com> - 0.1.0-2
- Mass rebuild 2013-12-27

* Tue Jun 11 2013 Christophe Fergeau <cfergeau@redhat.com> 0.1.0-1
- Update to upstream release 0.1.0

* Mon Mar 11 2013 Christophe Fergeau <cfergeau@redhat.com> 0.0.3-2
- Removed definition of BuildRoot and cleanup of BuildRoot in %clean
- Added missing arch to versioned Requires: %%{name} in the -devel package
- Don't include empty NEWS and ChangeLog in built RPM

* Wed Feb 20 2013 Christophe Fergeau <cfergeau@redhat.com> 0.0.3-1
- Initial import of libgovirt 0.0.3
Loading…
Cancel
Save