[libgovirt] Add support for VM pools



commit 602caca97435812366ed92c9db73eaf3c22e202c
Author: Iordan Iordanov <iiordanov gmail com>
Date:   Tue Dec 3 03:07:09 2013 -0500

    Add 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  |  238 +++++++++++++++++++++++++++++++++++++++++++++++
 govirt/ovirt-vm-pool.h  |   65 +++++++++++++
 govirt/ovirt-vm.c       |    4 -
 11 files changed, 390 insertions(+), 4 deletions(-)
---
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 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 61f8139..5977d5e 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..27edcd2
--- /dev/null
+++ b/govirt/ovirt-vm-pool.c
@@ -0,0 +1,238 @@
+/*
+ * ovirt-vm-pool.c: oVirt virtual machine pool
+ *
+ * Copyright (C) 2013 Iordan Iordanov <i 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"
+
+
+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));
+}
+
+
+gboolean ovirt_vm_pool_allocate_vm(OvirtVmPool *vm_pool, OvirtProxy *proxy, GError **error)
+{
+    return ovirt_resource_action(OVIRT_RESOURCE(vm_pool), proxy, "allocatevm", NULL, error);
+}
+
+
+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 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__ */
diff --git a/govirt/ovirt-vm.c b/govirt/ovirt-vm.c
index db393eb..07be61b 100644
--- a/govirt/ovirt-vm.c
+++ b/govirt/ovirt-vm.c
@@ -52,10 +52,6 @@ enum OvirtResponseStatus {
     OVIRT_RESPONSE_COMPLETE
 };
 
-ActionResponseParser response_parsers[] = {
-    [OVIRT_VM_ACTION_TICKET] = parse_ticket_status
-};
-
 enum {
     PROP_0,
     PROP_STATE,


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