[Spice-devel] VM pools and libgovirt
Christophe Fergeau
cfergeau at redhat.com
Tue Dec 3 09:21:22 PST 2013
On Tue, Dec 03, 2013 at 11:46:40AM -0500, i iordanov wrote:
> Would you like me to generate a patch with all the suggested changes and a
> better log entry?
I've been doing that actually, with various changes:
- renamed allocatevm to allocate_vm
- renamed _vmpool_ to _vm_pool
- moved ovirt_vm_pool_xml.c to ovirt_vm_pool.c as it was not that big
- used guint for the various VmPool properties
- detect parsing errors when parsing numbers
- fixed the copyright headers (the new files should be (C) 2013 yourself,
not (C) 2013 Red Hat Inc)
I still have these changes roughly split up if you don't like some of them
and want me to drop them.
Christophe
From 436eb3fd47ee1cc28dd9a2c68e3bf4c2c7827f60 Mon Sep 17 00:00:00 2001
From: Iordan Iordanov <iiordanov at gmail.com>
Date: Tue, 3 Dec 2013 03:07:09 -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 | 2 +
govirt/govirt.h | 1 +
govirt/govirt.sym | 7 +
govirt/ovirt-api.c | 28 ++++
govirt/ovirt-api.h | 1 +
govirt/ovirt-resource.c | 1 +
govirt/ovirt-utils.c | 45 ++++++
govirt/ovirt-utils.h | 2 +
govirt/ovirt-vm-pool.c | 368 ++++++++++++++++++++++++++++++++++++++++++++++++
govirt/ovirt-vm-pool.h | 65 +++++++++
10 files changed, 520 insertions(+)
create mode 100644 govirt/ovirt-vm-pool.c
create mode 100644 govirt/ovirt-vm-pool.h
diff --git a/govirt/Makefile.am b/govirt/Makefile.am
index d9e70a5..645545d 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-vm-pool.h \
ovirt-vm-display.h \
$(NULL)
@@ -62,6 +63,7 @@ libgovirt_la_SOURCES = \
ovirt-vm.c \
ovirt-vm-display.c \
ovirt-vm-xml.c \
+ ovirt-vm-pool.c \
$(NULL)
nodist_libgovirt_la_HEADERS = \
diff --git a/govirt/govirt.h b/govirt/govirt.h
index 69f878b..fb7756f 100644
--- a/govirt/govirt.h
+++ b/govirt/govirt.h
@@ -34,5 +34,6 @@
#include <govirt/ovirt-storage-domain.h>
#include <govirt/ovirt-vm.h>
#include <govirt/ovirt-vm-display.h>
+#include <govirt/ovirt-vm-pool.h>
#endif /* __OVIRT_H__ */
diff --git a/govirt/govirt.sym b/govirt/govirt.sym
index bc53901..49636d5 100644
--- a/govirt/govirt.sym
+++ b/govirt/govirt.sym
@@ -87,5 +87,12 @@ GOVIRT_0.2.1 {
ovirt_vm_get_cdroms;
} GOVIRT_0.2.0;
+GOVIRT_0.3.1 {
+ ovirt_api_get_vm_pools;
+
+ ovirt_vm_pool_get_type;
+ ovirt_vm_pool_new;
+ ovirt_vm_pool_allocate_vm;
+} GOVIRT_0.2.1;
# .... define new API here using predicted next version number ....
diff --git a/govirt/ovirt-api.c b/govirt/ovirt-api.c
index ddb2300..4b6d141 100644
--- a/govirt/ovirt-api.c
+++ b/govirt/ovirt-api.c
@@ -2,6 +2,7 @@
* ovirt-api.c: oVirt API entry point
*
* Copyright (C) 2012, 2013 Red Hat, Inc.
+ * Copyright (C) 2013 Iordan Iordanov <i at iiordanov.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -27,6 +28,7 @@
#include "ovirt-proxy.h"
#include "ovirt-rest-call.h"
#include "ovirt-api.h"
+#include "ovirt-vm-pool.h"
#include "govirt-private.h"
#include <rest/rest-xml-node.h>
@@ -41,6 +43,7 @@
struct _OvirtApiPrivate {
OvirtCollection *storage_domains;
OvirtCollection *vms;
+ OvirtCollection *vm_pools;
};
@@ -72,6 +75,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->vm_pools);
G_OBJECT_CLASS(ovirt_api_parent_class)->dispose(object);
}
@@ -131,6 +135,30 @@ OvirtCollection *ovirt_api_get_vms(OvirtApi *api)
return api->priv->vms;
}
+/**
+ * ovirt_api_get_vm_pools:
+ * @api: a #OvirtApi
+ *
+ * Return value: (transfer full):
+ */
+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");
+
+ return api->priv->vm_pools;
+}
+
/**
* ovirt_api_get_storage_domains:
diff --git a/govirt/ovirt-api.h b/govirt/ovirt-api.h
index d1de522..5f0d4e9 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_vm_pools(OvirtApi *api);
G_END_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..3b9593a 100644
--- a/govirt/ovirt-utils.c
+++ b/govirt/ovirt-utils.c
@@ -22,6 +22,7 @@
#include <config.h>
+#include <errno.h>
#include <string.h>
#include <rest/rest-xml-parser.h>
@@ -126,6 +127,50 @@ ovirt_utils_boolean_from_string(const char *value)
return (g_strcmp0(value, "true") == 0);
}
+G_GNUC_INTERNAL gboolean
+ovirt_utils_guint64_from_string(const char *value_str, guint64 *value)
+{
+ char *end_ptr;
+ guint64 result;
+
+ g_return_val_if_fail(value_str != NULL, FALSE);
+
+ result = g_ascii_strtoull(value_str, &end_ptr, 10);
+ if ((result == G_MAXUINT64) && (errno == ERANGE)) {
+ /* overflow */
+ return FALSE;
+ }
+ if ((result == 0) && (errno == EINVAL)) {
+ /* should not happen, invalid base */
+ return FALSE;
+ }
+ if (*end_ptr != '\0') {
+ return FALSE;
+ }
+
+ *value = result;
+
+ return TRUE;
+}
+
+G_GNUC_INTERNAL gboolean
+ovirt_utils_guint_from_string(const char *value_str, guint *value)
+{
+ guint64 value64;
+ gboolean success;
+
+ success = ovirt_utils_guint64_from_string(value_str, &value64);
+ if (!success) {
+ return FALSE;
+ }
+ if (value64 > G_MAXUINT32) {
+ return FALSE;
+ }
+
+ *value = (guint)value64;
+
+ return TRUE;
+}
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..f627c13 100644
--- a/govirt/ovirt-utils.h
+++ b/govirt/ovirt-utils.h
@@ -36,6 +36,8 @@ 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);
+gboolean ovirt_utils_guint64_from_string(const char *value_str, guint64 *value);
+gboolean ovirt_utils_guint_from_string(const char *value_str, guint *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-vm-pool.c b/govirt/ovirt-vm-pool.c
new file mode 100644
index 0000000..99a8444
--- /dev/null
+++ b/govirt/ovirt-vm-pool.c
@@ -0,0 +1,368 @@
+/*
+ * ovirt-vm-pool.c: oVirt virtual machine pool
+ *
+ * Copyright (C) 2013 Iordan Iordanov <i at iiordanov.com>
+ *
+ * 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/>.
+ */
+
+#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 *vm_pool, GError **error);
+static gboolean parse_action_response(RestProxyCall *call, OvirtVmPool *vm_pool,
+ ActionResponseParser response_parser,
+ GError **error);
+static gboolean ovirt_vm_pool_refresh_from_xml(OvirtVmPool *vm_pool, RestXmlNode *node);
+#define OVIRT_VM_POOL_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), OVIRT_TYPE_VM_POOL, OvirtVmPoolPrivate))
+
+struct _OvirtVmPoolPrivate {
+ guint prestarted_vms;
+ guint max_user_vms;
+ guint size;
+};
+
+G_DEFINE_TYPE(OvirtVmPool, ovirt_vm_pool, 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_vm_pool_get_property(GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ OvirtVmPool *vm_pool = OVIRT_VM_POOL(object);
+
+ switch (prop_id) {
+ case PROP_SIZE:
+ g_value_set_uint(value, vm_pool->priv->size);
+ break;
+ case PROP_PRESTARTED_VMS:
+ g_value_set_uint(value, vm_pool->priv->prestarted_vms);
+ break;
+ case PROP_MAX_USER_VMS:
+ g_value_set_uint(value, vm_pool->priv->max_user_vms);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ }
+}
+
+static void ovirt_vm_pool_set_property(GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ OvirtVmPool *vm_pool = OVIRT_VM_POOL(object);
+
+ switch (prop_id) {
+ case PROP_SIZE:
+ vm_pool->priv->size = g_value_get_uint(value);
+ break;
+ case PROP_PRESTARTED_VMS:
+ vm_pool->priv->prestarted_vms = g_value_get_uint(value);
+ break;
+ case PROP_MAX_USER_VMS:
+ vm_pool->priv->max_user_vms = g_value_get_uint(value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ }
+}
+
+static void ovirt_vm_pool_dispose(GObject *object)
+{
+ G_OBJECT_CLASS(ovirt_vm_pool_parent_class)->dispose(object);
+}
+
+static gboolean ovirt_vm_pool_init_from_xml(OvirtResource *resource,
+ RestXmlNode *node,
+ GError **error)
+{
+ gboolean parsed_ok;
+ OvirtResourceClass *parent_class;
+
+ parsed_ok = ovirt_vm_pool_refresh_from_xml(OVIRT_VM_POOL(resource), node);
+ if (!parsed_ok) {
+ return FALSE;
+ }
+ parent_class = OVIRT_RESOURCE_CLASS(ovirt_vm_pool_parent_class);
+
+ return parent_class->init_from_xml(resource, node, error);
+}
+
+static void ovirt_vm_pool_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_vm_pool_init_from_xml;
+ object_class->dispose = ovirt_vm_pool_dispose;
+ object_class->get_property = ovirt_vm_pool_get_property;
+ object_class->set_property = ovirt_vm_pool_set_property;
+
+ g_object_class_install_property(object_class,
+ PROP_SIZE,
+ g_param_spec_uint("size",
+ "Size of pool",
+ "The number of VMs in the pool",
+ 0,
+ G_MAXUINT,
+ 0,
+ G_PARAM_READWRITE));
+ g_object_class_install_property(object_class,
+ PROP_PRESTARTED_VMS,
+ g_param_spec_uint("prestarted_vms",
+ "Prestarted VMs",
+ "The number of VMs prestarted in the pool",
+ 0,
+ G_MAXUINT,
+ 0,
+ G_PARAM_READWRITE));
+ g_object_class_install_property(object_class,
+ PROP_MAX_USER_VMS,
+ g_param_spec_uint("max_user_vms",
+ "Max VMs per user",
+ "The number of VMs a user can allocate from the pool",
+ 0,
+ G_MAXUINT,
+ 0,
+ G_PARAM_READWRITE));
+}
+
+static void ovirt_vm_pool_init(G_GNUC_UNUSED OvirtVmPool *vm_pool)
+{
+ vm_pool->priv = OVIRT_VM_POOL_GET_PRIVATE(vm_pool);
+}
+
+OvirtVmPool *ovirt_vm_pool_new(void)
+{
+ return OVIRT_VM_POOL(g_initable_new(OVIRT_TYPE_VM_POOL, NULL, NULL, NULL));
+}
+
+static gboolean
+ovirt_vm_pool_action(OvirtVmPool *vm_pool, OvirtProxy *proxy, const char *action,
+ ActionResponseParser response_parser, GError **error)
+{
+ RestProxyCall *call;
+ const char *function;
+
+ g_return_val_if_fail(OVIRT_IS_VM_POOL(vm_pool), 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(vm_pool), 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, vm_pool);
+ /* Even in error cases we may have a response body describing
+ * the failure, try to parse that */
+ parse_action_response(call, vm_pool, 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, vm_pool, response_parser, error);
+
+ g_object_unref(G_OBJECT(call));
+
+ return TRUE;
+}
+
+gboolean ovirt_vm_pool_allocate_vm(OvirtVmPool *vm_pool, OvirtProxy *proxy, GError **error)
+{
+ return ovirt_vm_pool_action(vm_pool, 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 *vm_pool,
+ 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, vm_pool, 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;
+}
+
+
+static gboolean vm_pool_set_size_from_xml(OvirtVmPool *vm_pool, RestXmlNode *node)
+{
+ RestXmlNode *size_node;
+ size_node = rest_xml_node_find(node, "size");
+ if (size_node != NULL) {
+ guint size;
+ g_return_val_if_fail(size_node->content != NULL, FALSE);
+ if (!ovirt_utils_guint_from_string(size_node->content, &size)) {
+ return FALSE;
+ }
+ g_object_set(G_OBJECT(vm_pool), "size", size, NULL);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+static gboolean vm_pool_set_prestarted_vms_from_xml(OvirtVmPool *vm_pool, RestXmlNode *node)
+{
+ RestXmlNode *prestarted_vms_node;
+ prestarted_vms_node = rest_xml_node_find(node, "prestarted_vms");
+ if (prestarted_vms_node != NULL) {
+ guint prestarted_vms;
+ g_return_val_if_fail(prestarted_vms_node->content != NULL, FALSE);
+ if (!ovirt_utils_guint_from_string(prestarted_vms_node->content, &prestarted_vms)) {
+ return FALSE;
+ }
+ g_object_set(G_OBJECT(vm_pool), "prestarted_vms", prestarted_vms, NULL);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+static gboolean vm_pool_set_max_user_vms_from_xml(OvirtVmPool *vm_pool, 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) {
+ guint max_user_vms;
+ g_return_val_if_fail(max_user_vms_node->content != NULL, FALSE);
+ if (!ovirt_utils_guint_from_string(max_user_vms_node->content, &max_user_vms)) {
+ return FALSE;
+ }
+ g_object_set(G_OBJECT(vm_pool), "max_user_vms", max_user_vms, NULL);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+static gboolean ovirt_vm_pool_refresh_from_xml(OvirtVmPool *vm_pool, RestXmlNode *node)
+{
+ vm_pool_set_size_from_xml(vm_pool, node);
+ vm_pool_set_prestarted_vms_from_xml(vm_pool, node);
+ vm_pool_set_max_user_vms_from_xml(vm_pool, node);
+ return TRUE;
+}
diff --git a/govirt/ovirt-vm-pool.h b/govirt/ovirt-vm-pool.h
new file mode 100644
index 0000000..e4245cb
--- /dev/null
+++ b/govirt/ovirt-vm-pool.h
@@ -0,0 +1,65 @@
+/*
+ * ovirt-vm-pool.h: oVirt VM pool
+ *
+ * Copyright (C) 2013 Iordan Iordanov <i at iiordanov.com>
+ *
+ * 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/>.
+ */
+#ifndef __OVIRT_VM_POOL_H__
+#define __OVIRT_VM_POOL_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_VM_POOL (ovirt_vm_pool_get_type ())
+#define OVIRT_VM_POOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), OVIRT_TYPE_VM_POOL, OvirtVmPool))
+#define OVIRT_VM_POOL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), OVIRT_TYPE_VM_POOL, OvirtVmPoolClass))
+#define OVIRT_IS_VM_POOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OVIRT_TYPE_VM_POOL))
+#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;
+
+struct _OvirtVmPool
+{
+ OvirtResource parent;
+
+ OvirtVmPoolPrivate *priv;
+
+ /* Do not add fields to this struct */
+};
+
+struct _OvirtVmPoolClass
+{
+ OvirtResourceClass parent_class;
+
+ gpointer padding[20];
+};
+
+GType ovirt_vm_pool_get_type(void);
+OvirtVmPool *ovirt_vm_pool_new(void);
+
+gboolean ovirt_vm_pool_allocate_vm(OvirtVmPool *vm_pool, OvirtProxy *proxy, GError **error);
+
+G_END_DECLS
+
+#endif /* __OVIRT_VM_POOL_H__ */
--
1.8.4.2
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.freedesktop.org/archives/spice-devel/attachments/20131203/be349077/attachment-0001.pgp>
More information about the Spice-devel
mailing list