Re: VM pools and libgovirt

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Christophe,

On Mon, Dec 2, 2013 at 4:33 AM, Christophe Fergeau <cfergeau@xxxxxxxxxx> wrote:
Thanks a lot for working on that!

My pleasure! Attached find the patch, generated the way you wanted.

Cheers,
iordan

--
The conscious mind has only one thread of execution.
From d940ea24d8146a8d728ac5b7e38ec03eaf808001 Mon Sep 17 00:00:00 2001
From: Iordan Iordanov <iiordanov@xxxxxxxxx>
Date: Tue, 3 Dec 2013 02:58:45 -0500
Subject: [PATCH] - Added initial support for VM pools. - The library is now
 able to allocate VMs from the pool synchronously. - The
 attributes size, prestarted_vms, and max_user_vms are
 parsed.

---
 govirt/Makefile.am            |    4 +
 govirt/govirt-private.h       |    1 +
 govirt/ovirt-api.c            |   26 ++++
 govirt/ovirt-api.h            |    1 +
 govirt/ovirt-proxy.h          |    1 +
 govirt/ovirt-resource.c       |    1 +
 govirt/ovirt-utils.c          |    7 +
 govirt/ovirt-utils.h          |    1 +
 govirt/ovirt-vmpool-private.h |   40 ++++++
 govirt/ovirt-vmpool-xml.c     |   80 +++++++++++
 govirt/ovirt-vmpool.c         |  316 +++++++++++++++++++++++++++++++++++++++++
 govirt/ovirt-vmpool.h         |   67 +++++++++
 12 files changed, 545 insertions(+)
 create mode 100644 govirt/ovirt-vmpool-private.h
 create mode 100644 govirt/ovirt-vmpool-xml.c
 create mode 100644 govirt/ovirt-vmpool.c
 create mode 100644 govirt/ovirt-vmpool.h

diff --git a/govirt/Makefile.am b/govirt/Makefile.am
index d9e70a5..0eade7e 100644
--- a/govirt/Makefile.am
+++ b/govirt/Makefile.am
@@ -26,6 +26,7 @@ libgovirt_la_HEADERS =						\
 	ovirt-storage-domain.h					\
 	ovirt-types.h						\
 	ovirt-vm.h						\
+	ovirt-vmpool.h						\
 	ovirt-vm-display.h					\
 	$(NULL)
 
@@ -42,6 +43,7 @@ noinst_HEADERS =						\
 	ovirt-storage-domain-private.h				\
 	ovirt-utils.h						\
 	ovirt-vm-private.h					\
+	ovirt-vmpool-private.h					\
 	$(NULL)
 
 libgovirt_la_SOURCES =						\
@@ -62,6 +64,8 @@ libgovirt_la_SOURCES =						\
 	ovirt-vm.c						\
 	ovirt-vm-display.c					\
 	ovirt-vm-xml.c						\
+	ovirt-vmpool.c						\
+	ovirt-vmpool-xml.c						\
 	$(NULL)
 
 nodist_libgovirt_la_HEADERS =					\
diff --git a/govirt/govirt-private.h b/govirt/govirt-private.h
index 972ebac..3258aae 100644
--- a/govirt/govirt-private.h
+++ b/govirt/govirt-private.h
@@ -33,6 +33,7 @@
 #include <govirt/ovirt-storage-domain-private.h>
 #include <govirt/ovirt-utils.h>
 #include <govirt/ovirt-vm-private.h>
+#include <govirt/ovirt-vmpool-private.h>
 #include <govirt/glib-compat.h>
 
 #endif /* __OVIRT_PRIVATE_H__ */
diff --git a/govirt/ovirt-api.c b/govirt/ovirt-api.c
index ddb2300..bdcc576 100644
--- a/govirt/ovirt-api.c
+++ b/govirt/ovirt-api.c
@@ -41,6 +41,7 @@
 struct _OvirtApiPrivate {
     OvirtCollection *storage_domains;
     OvirtCollection *vms;
+    OvirtCollection *vmpools;
 };
 
 
@@ -72,6 +73,7 @@ static void ovirt_api_dispose(GObject *object)
 
     g_clear_object(&api->priv->storage_domains);
     g_clear_object(&api->priv->vms);
+    g_clear_object(&api->priv->vmpools);
 
     G_OBJECT_CLASS(ovirt_api_parent_class)->dispose(object);
 }
@@ -131,6 +133,30 @@ OvirtCollection *ovirt_api_get_vms(OvirtApi *api)
     return api->priv->vms;
 }
 
+/**
+ * ovirt_api_get_vmpools:
+ * @api: a #OvirtApi
+ *
+ * Return value: (transfer full):
+ */
+OvirtCollection *ovirt_api_get_vmpools(OvirtApi *api)
+{
+    const char *href;
+
+    g_return_val_if_fail(OVIRT_IS_API(api), NULL);
+
+    if (api->priv->vmpools != NULL)
+        return api->priv->vmpools;
+
+    href = ovirt_resource_get_sub_collection(OVIRT_RESOURCE(api), "vmpools");
+    if (href == NULL)
+        return NULL;
+
+    api->priv->vmpools = ovirt_collection_new(href, "vmpools", OVIRT_TYPE_VMPOOL, "vmpool");
+
+    return api->priv->vmpools;
+}
+
 
 /**
  * ovirt_api_get_storage_domains:
diff --git a/govirt/ovirt-api.h b/govirt/ovirt-api.h
index d1de522..3af1bc0 100644
--- a/govirt/ovirt-api.h
+++ b/govirt/ovirt-api.h
@@ -63,6 +63,7 @@ OvirtApi *ovirt_api_new(void);
 
 OvirtCollection *ovirt_api_get_storage_domains(OvirtApi *api);
 OvirtCollection *ovirt_api_get_vms(OvirtApi *api);
+OvirtCollection *ovirt_api_get_vmpools(OvirtApi *api);
 
 G_END_DECLS
 
diff --git a/govirt/ovirt-proxy.h b/govirt/ovirt-proxy.h
index 985b76d..83d7024 100644
--- a/govirt/ovirt-proxy.h
+++ b/govirt/ovirt-proxy.h
@@ -26,6 +26,7 @@
 #include <govirt/ovirt-api.h>
 #include <govirt/ovirt-types.h>
 #include <govirt/ovirt-vm.h>
+#include <govirt/ovirt-vmpool.h>
 
 G_BEGIN_DECLS
 
diff --git a/govirt/ovirt-resource.c b/govirt/ovirt-resource.c
index fca06e8..81241be 100644
--- a/govirt/ovirt-resource.c
+++ b/govirt/ovirt-resource.c
@@ -25,6 +25,7 @@
 #include <string.h>
 
 #include <rest/rest-xml-node.h>
+#include <rest/rest-xml-parser.h>
 
 #include "govirt-private.h"
 #include "ovirt-error.h"
diff --git a/govirt/ovirt-utils.c b/govirt/ovirt-utils.c
index 618992a..6799ddb 100644
--- a/govirt/ovirt-utils.c
+++ b/govirt/ovirt-utils.c
@@ -126,6 +126,13 @@ ovirt_utils_boolean_from_string(const char *value)
     return (g_strcmp0(value, "true") == 0);
 }
 
+G_GNUC_INTERNAL guint64
+ovirt_utils_guint64_from_string(const char *value)
+{
+    g_return_val_if_fail(value != NULL, FALSE);
+
+    return g_ascii_strtoull(value, NULL, 10);
+}
 
 G_GNUC_INTERNAL const char *ovirt_utils_strip_api_base_dir(const char *path)
 {
diff --git a/govirt/ovirt-utils.h b/govirt/ovirt-utils.h
index 935b029..df78e9c 100644
--- a/govirt/ovirt-utils.h
+++ b/govirt/ovirt-utils.h
@@ -36,6 +36,7 @@ gboolean ovirt_utils_gerror_from_xml_fault(RestXmlNode *root, GError **error);
 const char *ovirt_utils_genum_get_nick (GType enum_type, gint value);
 int ovirt_utils_genum_get_value (GType enum_type, const char *nick,
                                  gint default_value);
+guint64 ovirt_utils_guint64_from_string(const char *value);
 gboolean ovirt_utils_boolean_from_string(const char *value);
 const char *ovirt_utils_strip_api_base_dir(const char *path);
 
diff --git a/govirt/ovirt-vmpool-private.h b/govirt/ovirt-vmpool-private.h
new file mode 100644
index 0000000..19ffc27
--- /dev/null
+++ b/govirt/ovirt-vmpool-private.h
@@ -0,0 +1,40 @@
+
+/*
+ * ovirt-vmpool-private.h: oVirt VM pool private header
+ *
+ * Copyright (C) 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: Iordan Iordanov <i@xxxxxxxxxxxxx>
+ */
+#ifndef __OVIRT_VMPOOL_PRIVATE_H__
+#define __OVIRT_VMPOOL_PRIVATE_H__
+
+#include <ovirt-vmpool.h>
+#include <rest/rest-xml-node.h>
+
+G_BEGIN_DECLS
+
+typedef enum {
+    OVIRT_VMPOOL_ACTION_ALLOCATEVM
+} OvirtVmPoolAction;
+
+gboolean ovirt_vmpool_refresh_from_xml(OvirtVmPool *vm, RestXmlNode *node);
+OvirtVmPool *ovirt_vmpool_new_from_xml(RestXmlNode *node, GError **error);
+
+G_END_DECLS
+
+#endif /* __OVIRT_VMPOOL_PRIVATE_H__ */
diff --git a/govirt/ovirt-vmpool-xml.c b/govirt/ovirt-vmpool-xml.c
new file mode 100644
index 0000000..ad17b8d
--- /dev/null
+++ b/govirt/ovirt-vmpool-xml.c
@@ -0,0 +1,80 @@
+/*
+ * ovirt-vmpool-xml.c
+ *
+ * Copyright (C) 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: Iordan Iordanov <i@xxxxxxxxxxxxx>
+ */
+#include <config.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "ovirt-enum-types.h"
+#include "ovirt-utils.h"
+#include "ovirt-vmpool.h"
+#include "ovirt-vmpool-private.h"
+
+static gboolean vmpool_set_size_from_xml(OvirtVmPool *vmpool, RestXmlNode *node)
+{
+    RestXmlNode *size_node;
+    size_node = rest_xml_node_find(node, "size");
+    if (size_node != NULL) {
+    	gint size;
+        g_return_val_if_fail(size_node->content != NULL, FALSE);
+        size = (gint)ovirt_utils_guint64_from_string(size_node->content);
+        g_object_set(G_OBJECT(vmpool), "size", size, NULL);
+        return TRUE;
+    }
+    return FALSE;
+}
+
+static gboolean vmpool_set_prestarted_vms_from_xml(OvirtVmPool *vmpool, RestXmlNode *node)
+{
+    RestXmlNode *prestarted_vms_node;
+    prestarted_vms_node = rest_xml_node_find(node, "prestarted_vms");
+    if (prestarted_vms_node != NULL) {
+    	gint prestarted_vms;
+        g_return_val_if_fail(prestarted_vms_node->content != NULL, FALSE);
+        prestarted_vms = (gint)ovirt_utils_guint64_from_string(prestarted_vms_node->content);
+        g_object_set(G_OBJECT(vmpool), "prestarted_vms", prestarted_vms, NULL);
+        return TRUE;
+    }
+    return FALSE;
+}
+
+static gboolean vmpool_set_max_user_vms_from_xml(OvirtVmPool *vmpool, RestXmlNode *node)
+{
+    RestXmlNode *max_user_vms_node;
+    max_user_vms_node = rest_xml_node_find(node, "max_user_vms");
+    if (max_user_vms_node != NULL) {
+        gint max_user_vms;
+        g_return_val_if_fail(max_user_vms_node->content != NULL, FALSE);
+        max_user_vms = (gint)ovirt_utils_guint64_from_string(max_user_vms_node->content);
+        g_object_set(G_OBJECT(vmpool), "max_user_vms", max_user_vms, NULL);
+        return TRUE;
+    }
+    return FALSE;
+}
+
+G_GNUC_INTERNAL gboolean ovirt_vmpool_refresh_from_xml(OvirtVmPool *vmpool, RestXmlNode *node)
+{
+	vmpool_set_size_from_xml(vmpool, node);
+	vmpool_set_prestarted_vms_from_xml(vmpool, node);
+	vmpool_set_max_user_vms_from_xml(vmpool, node);
+    return TRUE;
+}
diff --git a/govirt/ovirt-vmpool.c b/govirt/ovirt-vmpool.c
new file mode 100644
index 0000000..93180a8
--- /dev/null
+++ b/govirt/ovirt-vmpool.c
@@ -0,0 +1,316 @@
+/*
+ * ovirt-vmpool.c: oVirt virtual machine pool
+ *
+ * Copyright (C) 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: Iordan Iordanov <i@xxxxxxxxxxxxx>
+ */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <rest/rest-xml-node.h>
+#include <rest/rest-xml-parser.h>
+
+#include "govirt.h"
+#include "govirt-private.h"
+
+
+typedef gboolean (*ActionResponseParser)(RestXmlNode *node, OvirtVmPool *vmpool, GError **error);
+static gboolean parse_action_response(RestProxyCall *call, OvirtVmPool *vmpool,
+                                      ActionResponseParser response_parser,
+                                      GError **error);
+#define OVIRT_VMPOOL_GET_PRIVATE(obj)                         \
+        (G_TYPE_INSTANCE_GET_PRIVATE((obj), OVIRT_TYPE_VMPOOL, OvirtVmPoolPrivate))
+
+struct _OvirtVmPoolPrivate {
+	gint prestarted_vms;
+	gint max_user_vms;
+	gint size;
+};
+
+G_DEFINE_TYPE(OvirtVmPool, ovirt_vmpool, OVIRT_TYPE_RESOURCE);
+
+enum OvirtResponseStatus {
+    OVIRT_RESPONSE_UNKNOWN,
+    OVIRT_RESPONSE_FAILED,
+    OVIRT_RESPONSE_PENDING,
+    OVIRT_RESPONSE_IN_PROGRESS,
+    OVIRT_RESPONSE_COMPLETE
+};
+
+enum {
+    PROP_0,
+    PROP_SIZE,
+    PROP_PRESTARTED_VMS,
+    PROP_MAX_USER_VMS
+};
+
+static void ovirt_vmpool_get_property(GObject *object,
+                                  guint prop_id,
+                                  GValue *value,
+                                  GParamSpec *pspec)
+{
+    OvirtVmPool *vmpool = OVIRT_VMPOOL(object);
+
+    switch (prop_id) {
+    case PROP_SIZE:
+        g_value_set_int(value, vmpool->priv->size);
+        break;
+    case PROP_PRESTARTED_VMS:
+        g_value_set_int(value, vmpool->priv->prestarted_vms);
+        break;
+    case PROP_MAX_USER_VMS:
+    	g_value_set_int(value, vmpool->priv->max_user_vms);
+        break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+    }
+}
+
+static void ovirt_vmpool_set_property(GObject *object,
+                                  guint prop_id,
+                                  const GValue *value,
+                                  GParamSpec *pspec)
+{
+    OvirtVmPool *vmpool = OVIRT_VMPOOL(object);
+
+    switch (prop_id) {
+    case PROP_SIZE:
+        vmpool->priv->size = g_value_get_int(value);
+        break;
+    case PROP_PRESTARTED_VMS:
+        vmpool->priv->prestarted_vms = g_value_get_int(value);
+        break;
+    case PROP_MAX_USER_VMS:
+        vmpool->priv->max_user_vms = g_value_get_int(value);
+        break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+    }
+}
+
+static void ovirt_vmpool_dispose(GObject *object)
+{
+    G_OBJECT_CLASS(ovirt_vmpool_parent_class)->dispose(object);
+}
+
+static gboolean ovirt_vmpool_init_from_xml(OvirtResource *resource,
+                                       RestXmlNode *node,
+                                       GError **error)
+{
+    gboolean parsed_ok;
+    OvirtResourceClass *parent_class;
+
+    parsed_ok = ovirt_vmpool_refresh_from_xml(OVIRT_VMPOOL(resource), node);
+    if (!parsed_ok) {
+        return FALSE;
+    }
+    parent_class = OVIRT_RESOURCE_CLASS(ovirt_vmpool_parent_class);
+
+    return parent_class->init_from_xml(resource, node, error);
+}
+
+static void ovirt_vmpool_class_init(OvirtVmPoolClass *klass)
+{
+    GObjectClass *object_class = G_OBJECT_CLASS(klass);
+    OvirtResourceClass *resource_class = OVIRT_RESOURCE_CLASS(klass);
+
+    g_type_class_add_private(klass, sizeof(OvirtVmPoolPrivate));
+
+    resource_class->init_from_xml = ovirt_vmpool_init_from_xml;
+    object_class->dispose = ovirt_vmpool_dispose;
+    object_class->get_property = ovirt_vmpool_get_property;
+    object_class->set_property = ovirt_vmpool_set_property;
+
+    g_object_class_install_property(object_class,
+                                    PROP_SIZE,
+                                    g_param_spec_int("size",
+                                                       "Size of pool",
+                                                       "The number of VMs in the pool",
+                                                       G_MININT,
+                                                       G_MAXINT,
+                                                       0,
+                                                       G_PARAM_READWRITE));
+    g_object_class_install_property(object_class,
+                                    PROP_PRESTARTED_VMS,
+                                    g_param_spec_int("prestarted_vms",
+                                                       "Prestarted VMs",
+                                                       "The number of VMs prestarted in the pool",
+                                                       G_MININT,
+                                                       G_MAXINT,
+                                                       0,
+                                                       G_PARAM_READWRITE));
+    g_object_class_install_property(object_class,
+                                    PROP_MAX_USER_VMS,
+                                    g_param_spec_int("max_user_vms",
+                                                       "Max VMs per user",
+                                                       "The number of VMs a user can allocate from the pool",
+                                                       G_MININT,
+                                                       G_MAXINT,
+                                                       0,
+                                                       G_PARAM_READWRITE));
+}
+
+static void ovirt_vmpool_init(G_GNUC_UNUSED OvirtVmPool *vmpool)
+{
+	vmpool->priv = OVIRT_VMPOOL_GET_PRIVATE(vmpool);
+}
+
+OvirtVmPool *ovirt_vmpool_new_from_xml(RestXmlNode *node, GError **error)
+{
+    return OVIRT_VMPOOL(g_initable_new(OVIRT_TYPE_VMPOOL, NULL, error,
+                                   "xml-node", node, NULL));
+}
+
+OvirtVmPool *ovirt_vmpool_new(void)
+{
+    return OVIRT_VMPOOL(g_initable_new(OVIRT_TYPE_VMPOOL, NULL, NULL, NULL));
+}
+
+static gboolean
+ovirt_vmpool_action(OvirtVmPool *vmpool, OvirtProxy *proxy, const char *action,
+                ActionResponseParser response_parser, GError **error)
+{
+    RestProxyCall *call;
+    const char *function;
+
+    g_return_val_if_fail(OVIRT_IS_VMPOOL(vmpool), FALSE);
+    g_return_val_if_fail(action != NULL, FALSE);
+    g_return_val_if_fail(OVIRT_IS_PROXY(proxy), FALSE);
+    g_return_val_if_fail((error == NULL) || (*error == NULL), FALSE);
+
+    function = ovirt_resource_get_action(OVIRT_RESOURCE(vmpool), action);
+    function = ovirt_utils_strip_api_base_dir(function);
+    g_return_val_if_fail(function != NULL, FALSE);
+
+    call = REST_PROXY_CALL(ovirt_action_rest_call_new(REST_PROXY(proxy)));
+    rest_proxy_call_set_method(call, "POST");
+    rest_proxy_call_set_function(call, function);
+    rest_proxy_call_add_param(call, "async", "false");
+
+    if (!rest_proxy_call_sync(call, error)) {
+        GError *call_error = NULL;
+        g_warning("Error while running %s on %p", action, vmpool);
+        /* Even in error cases we may have a response body describing
+         * the failure, try to parse that */
+        parse_action_response(call, vmpool, response_parser, &call_error);
+        if (call_error != NULL) {
+            g_clear_error(error);
+            g_propagate_error(error, call_error);
+        }
+
+        g_object_unref(G_OBJECT(call));
+        return FALSE;
+    }
+
+    parse_action_response(call, vmpool, response_parser, error);
+
+    g_object_unref(G_OBJECT(call));
+
+    return TRUE;
+}
+
+gboolean ovirt_vmpool_allocatevm(OvirtVmPool *vmpool, OvirtProxy *proxy, GError **error)
+{
+    return ovirt_vmpool_action(vmpool, proxy, "allocatevm", NULL, error);
+}
+
+static enum OvirtResponseStatus parse_action_status(RestXmlNode *root,
+                                                    GError **error)
+{
+    RestXmlNode *node;
+    const char *status_key = g_intern_string("status");
+    const char *state_key = g_intern_string("state");
+
+    g_return_val_if_fail(g_strcmp0(root->name, "action") == 0,
+                         OVIRT_RESPONSE_UNKNOWN);
+    g_return_val_if_fail(error == NULL || *error == NULL,
+                         OVIRT_RESPONSE_UNKNOWN);
+
+    node = g_hash_table_lookup(root->children, status_key);
+    if (node == NULL) {
+        g_set_error(error, OVIRT_ERROR, OVIRT_ERROR_PARSING_FAILED, "could not find 'status' node");
+        g_return_val_if_reached(OVIRT_RESPONSE_UNKNOWN);
+    }
+    node = g_hash_table_lookup(node->children, state_key);
+    if (node == NULL) {
+        g_set_error(error, OVIRT_ERROR, OVIRT_ERROR_PARSING_FAILED, "could not find 'state' node");
+        g_return_val_if_reached(OVIRT_RESPONSE_UNKNOWN);
+    }
+    g_debug("State: %s\n", node->content);
+    if (g_strcmp0(node->content, "complete") == 0) {
+        return OVIRT_RESPONSE_COMPLETE;
+    } else if (g_strcmp0(node->content, "pending") == 0) {
+        g_set_error(error, OVIRT_ERROR, OVIRT_ERROR_ACTION_FAILED, "action is pending");
+        return OVIRT_RESPONSE_PENDING;
+    } else if (g_strcmp0(node->content, "in_progress") == 0) {
+        g_set_error(error, OVIRT_ERROR, OVIRT_ERROR_ACTION_FAILED, "action is in progress");
+        return OVIRT_RESPONSE_IN_PROGRESS;
+    } else if (g_strcmp0(node->content, "failed") == 0) {
+        g_set_error(error, OVIRT_ERROR, OVIRT_ERROR_ACTION_FAILED, "action has failed");
+        return OVIRT_RESPONSE_FAILED;
+    }
+
+    g_set_error(error, OVIRT_ERROR, OVIRT_ERROR_PARSING_FAILED, "unknown action failure");
+    g_return_val_if_reached(OVIRT_RESPONSE_UNKNOWN);
+}
+
+
+static gboolean
+parse_action_response(RestProxyCall *call, OvirtVmPool *vmpool,
+                      ActionResponseParser response_parser, GError **error)
+{
+    RestXmlNode *root;
+    gboolean result;
+
+    result = FALSE;
+    root = ovirt_rest_xml_node_from_call(call);
+
+    if (g_strcmp0(root->name, "action") == 0) {
+        enum OvirtResponseStatus status;
+
+        status = parse_action_status(root, error);
+        if (status  == OVIRT_RESPONSE_COMPLETE) {
+            if (response_parser) {
+                result = response_parser(root, vmpool, error);
+            } else {
+                result = TRUE;
+            }
+        } if (status == OVIRT_RESPONSE_FAILED) {
+            const char *fault_key = g_intern_string("fault");
+            GError *fault_error = NULL;
+            RestXmlNode *fault_node = NULL;
+
+            fault_node = g_hash_table_lookup(root->children, fault_key);
+            if (fault_node != NULL) {
+                ovirt_utils_gerror_from_xml_fault(fault_node, &fault_error);
+                if (fault_error != NULL) {
+                    g_clear_error(error);
+                    g_propagate_error(error, fault_error);
+                }
+            }
+        }
+    } else {
+        g_warn_if_reached();
+    }
+
+    rest_xml_node_unref(root);
+
+    return result;
+}
+
diff --git a/govirt/ovirt-vmpool.h b/govirt/ovirt-vmpool.h
new file mode 100644
index 0000000..8894164
--- /dev/null
+++ b/govirt/ovirt-vmpool.h
@@ -0,0 +1,67 @@
+/*
+ * ovirt-vmpool.h: oVirt VM pool
+ *
+ * Copyright (C) 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: Iordan Iordanov <i@xxxxxxxxxxxxx>
+ */
+#ifndef __OVIRT_VMPOOL_H__
+#define __OVIRT_VMPOOL_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_VMPOOL            (ovirt_vmpool_get_type ())
+#define OVIRT_VMPOOL(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), OVIRT_TYPE_VMPOOL, OvirtVmPool))
+#define OVIRT_VMPOOL_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), OVIRT_TYPE_VMPOOL, OvirtVmPoolClass))
+#define OVIRT_IS_VMPOOL(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OVIRT_TYPE_VMPOOL))
+#define OVIRT_IS_VMPOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), OVIRT_TYPE_VMPOOL))
+#define OVIRT_VMPOOL_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), OVIRT_TYPE_VMPOOL, OvirtVmPoolClass))
+
+typedef struct _OvirtVmPool OvirtVmPool;
+typedef struct _OvirtVmPoolPrivate OvirtVmPoolPrivate;
+typedef struct _OvirtVmPoolClass OvirtVmPoolClass;
+
+struct _OvirtVmPool
+{
+    OvirtResource parent;
+
+    OvirtVmPoolPrivate *priv;
+
+    /* Do not add fields to this struct */
+};
+
+struct _OvirtVmPoolClass
+{
+    OvirtResourceClass parent_class;
+
+    gpointer padding[20];
+};
+
+GType ovirt_vmpool_get_type(void);
+OvirtVmPool *ovirt_vmpool_new(void);
+
+gboolean ovirt_vmpool_allocatevm(OvirtVmPool *vmpool, OvirtProxy *proxy, GError **error);
+
+G_END_DECLS
+
+#endif /* __OVIRT_VMPOOL_H__ */
-- 
1.7.9.5

_______________________________________________
Spice-devel mailing list
Spice-devel@xxxxxxxxxxxxxxxxxxxxx
http://lists.freedesktop.org/mailman/listinfo/spice-devel

[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]     [Monitors]