[virt-tools-list] [virt-viewer 07/20] Add OvirtProxy class

Christophe Fergeau cfergeau at redhat.com
Wed Jun 13 12:23:15 UTC 2012


This class is used to access the oVirt manager through its REST API
and get the URL and credentials to use to access the corresponding VM
using SPICE.
---
 src/Makefile.am   |    2 +
 src/ovirt-proxy.c |  661 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/ovirt-proxy.h |   70 ++++++
 3 files changed, 733 insertions(+)
 create mode 100644 src/ovirt-proxy.c
 create mode 100644 src/ovirt-proxy.h

diff --git a/src/Makefile.am b/src/Makefile.am
index cd0e988..733fd42 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -52,12 +52,14 @@ BUILT_SOURCES =				\
 CLEANFILES = $(BUILT_SOURCES)
 
 OVIRT_HEADER_FILES =			\
+	ovirt-proxy.h			\
 	ovirt-rest-call.h		\
 	ovirt-vm.h			\
 	ovirt-vm-display.h		\
 	$(NULL)
 
 COMMON_SOURCES +=			\
+	ovirt-proxy.c			\
 	ovirt-rest-call.c		\
 	ovirt-vm.c			\
 	ovirt-vm-display.c		\
diff --git a/src/ovirt-proxy.c b/src/ovirt-proxy.c
new file mode 100644
index 0000000..653c3eb
--- /dev/null
+++ b/src/ovirt-proxy.c
@@ -0,0 +1,661 @@
+/*
+ * ovirt-proxy.c
+ *
+ * Copyright (C) 2011, 2012 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ *
+ * Author: Christophe Fergeau <cfergeau at redhat.com>
+ */
+
+#undef OVIRT_DEBUG
+#include <config.h>
+
+#include "ovirt-rest-call.h"
+#include "ovirt-proxy.h"
+#include "ovirt-vm.h"
+#include "ovirt-vm-display.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <rest/rest-proxy.h>
+#include <rest/rest-xml-node.h>
+#include <rest/rest-xml-parser.h>
+
+G_DEFINE_TYPE (OvirtProxy, ovirt_proxy, G_TYPE_OBJECT);
+
+struct _OvirtProxyPrivate {
+    RestProxy *rest_proxy;
+    GHashTable *vms;
+};
+
+#define OVIRT_PROXY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), OVIRT_TYPE_PROXY, OvirtProxyPrivate))
+
+enum {
+    PROP_0,
+    PROP_URI,
+};
+
+#define ADMIN_LOGIN "admin at internal"
+#define ADMIN_PASSWORD "XXXXXXX"
+#define API_ENTRY_POINT "/api/"
+
+enum OvirtResponseStatus {
+    OVIRT_RESPONSE_UNKNOWN,
+    OVIRT_RESPONSE_FAILED,
+    OVIRT_RESPONSE_PENDING,
+    OVIRT_RESPONSE_IN_PROGRESS,
+    OVIRT_RESPONSE_COMPLETE
+};
+
+
+#ifdef OVIRT_DEBUG
+static void dump_display(OvirtVmDisplay *display)
+{
+    OvirtVmDisplayType type;
+    guint monitor_count;
+    gchar *address;
+    guint port;
+    gchar *ticket;
+    guint expiry;
+
+    g_object_get(G_OBJECT(display),
+                 "type", &type,
+                 "monitor-count", &monitor_count,
+                 "address", &address,
+                 "port", &port,
+                 "ticket", &ticket,
+                 "expiry", &expiry,
+                 NULL);
+
+    g_print("\tDisplay:\n");
+    g_print("\t\tType: %s\n", (type == OVIRT_VM_DISPLAY_VNC)?"vnc":"spice");
+    g_print("\t\tMonitors: %d\n", monitor_count);
+    g_print("\t\tAddress: %s\n", address);
+    g_print("\t\tPort: %d\n", port);
+    g_print("\t\tTicket: %s\n", ticket);
+    g_print("\t\tExpiry: %d\n", expiry);
+    g_free(address);
+    g_free(ticket);
+}
+
+static void dump_key(gpointer key, gpointer value, gpointer user_data)
+{
+    g_print("[%s] -> %p\n", (char *)key, value);
+}
+
+static void dump_action(gpointer key, gpointer value, gpointer user_data)
+{
+    g_print("\t\t%s -> %s\n", (char *)key, (char *)value);
+}
+
+static void dump_vm(OvirtVm *vm)
+{
+    gchar *name;
+    gchar *uuid;
+    gchar *href;
+    OvirtVmState state;
+    GHashTable *actions = NULL;
+    OvirtVmDisplay *display;
+
+    g_object_get(G_OBJECT(vm),
+                 "name", &name,
+                 "uuid", &uuid,
+                 "href", &href,
+                 "state", &state,
+                 "display", &display,
+                 NULL);
+
+
+    g_print("VM:\n");
+    g_print("\tName: %s\n", name);
+    g_print("\tuuid: %s\n", uuid);
+    g_print("\thref: %s\n", href);
+    g_print("\tState: %s\n", (state == OVIRT_VM_STATE_UP)?"up":"down");
+    if (actions != NULL) {
+        g_print("\tActions:\n");
+        g_hash_table_foreach(actions, dump_action, NULL);
+        g_hash_table_unref(actions);
+    }
+    if (display != NULL) {
+        dump_display(display);
+        g_object_unref(display);
+    }
+    g_free(name);
+    g_free(uuid);
+    g_free(href);
+}
+#endif
+
+static gboolean vm_set_name_from_xml(OvirtVm *vm, RestXmlNode *node)
+{
+    RestXmlNode *name_node;
+
+    name_node = rest_xml_node_find(node, "name");
+    if (name_node != NULL) {
+        g_return_val_if_fail(name_node->content != NULL, FALSE);
+        g_object_set(G_OBJECT(vm), "name", name_node->content, NULL);
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+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 *monitors_key = g_intern_string("monitors");
+
+    if (root == NULL) {
+        return FALSE;
+    }
+    root = g_hash_table_lookup(root->children, display_key);
+    g_return_val_if_fail(root != NULL, 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);
+        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);
+    }
+
+    /* 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;
+}
+
+static gboolean vm_set_state_from_xml(OvirtVm *vm, RestXmlNode *node)
+{
+    RestXmlNode *state;
+
+    state = rest_xml_node_find(node, "status");
+    state = rest_xml_node_find(state, "state");
+    if (state != NULL) {
+        gboolean res = FALSE;
+        g_return_val_if_fail(state->content != NULL, FALSE);
+        if (strcmp(state->content, "down") == 0) {
+            g_object_set(G_OBJECT(vm), "state", OVIRT_VM_STATE_DOWN, NULL);
+            res = TRUE;
+        } else if (strcmp(state->content, "up") == 0) {
+            /* FIXME: check "UP" state name in the rsdl file */
+            g_object_set(G_OBJECT(vm), "state", OVIRT_VM_STATE_UP, NULL);
+            res = TRUE;
+        } else {
+            g_warning("Couldn't parse VM state: %s", state->content);
+        }
+        return res;
+    }
+
+    return FALSE;
+}
+
+static gboolean vm_set_actions_from_xml(OvirtVm *vm, RestXmlNode *node)
+{
+    RestXmlNode *link;
+    RestXmlNode *rest_actions;
+    const char *link_key = g_intern_string("link");
+
+    rest_actions = rest_xml_node_find(node, "actions");
+    if (rest_actions == NULL) {
+        return FALSE;
+    }
+
+    link = g_hash_table_lookup(rest_actions->children, link_key);
+    if (link == NULL)
+        return FALSE;
+
+    for (; link != NULL; link = link->next) {
+        const char *link_name;
+        const char *href;
+
+        g_warn_if_fail(link != NULL);
+        g_warn_if_fail(link->name != NULL);
+        g_warn_if_fail(strcmp(link->name, "link") == 0);
+
+        link_name = rest_xml_node_get_attr(link, "rel");
+        href = rest_xml_node_get_attr(link, "href");
+        if (g_str_has_prefix(href, API_ENTRY_POINT)) {
+            href += strlen(API_ENTRY_POINT);
+        } else {
+            /* action href should always be prefixed by /api/ */
+            /* it would be easier to remove /api/ from the RestProxy base
+             * URL but unfortunately I couldn't get this to work
+             */
+            g_warn_if_reached();
+        }
+
+        if ((link_name != NULL) && (href != NULL)) {
+            ovirt_vm_add_action(vm, link_name, href);
+        }
+    }
+
+    return TRUE;
+}
+
+static OvirtVm *xml_to_vm(RestXmlNode *node)
+{
+    OvirtVm *vm;
+    const char *uuid;
+    const char *href;
+
+
+    uuid = rest_xml_node_get_attr(node, "id");
+    g_return_val_if_fail(uuid != NULL, NULL);
+    href = rest_xml_node_get_attr(node, "href");
+    g_return_val_if_fail(href != NULL, NULL);
+
+    vm = ovirt_vm_new();
+    g_object_set(G_OBJECT(vm), "uuid", uuid, "href", href, NULL);
+
+    vm_set_name_from_xml(vm, node);
+    vm_set_state_from_xml(vm, node);
+    vm_set_actions_from_xml(vm, node);
+    vm_set_display_from_xml(vm, node);
+
+    return vm;
+}
+
+static GHashTable *parse_vms_xml(RestProxyCall *call)
+{
+    RestXmlParser *parser;
+    RestXmlNode *root;
+    RestXmlNode *xml_vms;
+    RestXmlNode *node;
+    GHashTable *vms;
+    const char *vm_key = g_intern_string("vm");
+
+    parser = rest_xml_parser_new ();
+
+    root = rest_xml_parser_parse_from_data (parser,
+            rest_proxy_call_get_payload (call),
+            rest_proxy_call_get_payload_length (call));
+
+    vms = g_hash_table_new_full(g_str_hash, g_str_equal,
+                                g_free, (GDestroyNotify)g_object_unref);
+#ifdef OVIRT_DEBUG
+    g_hash_table_foreach(root->children, dump_key, NULL);
+#endif
+    xml_vms = g_hash_table_lookup(root->children, vm_key);
+    for (node = xml_vms; node != NULL; node = node->next) {
+        OvirtVm *vm;
+        gchar *name;
+        vm = xml_to_vm(node);
+#ifdef OVIRT_DEBUG
+        dump_vm(vm);
+#endif
+        if (!OVIRT_IS_VM(vm)) {
+            g_message("Failed to parse XML VM description");
+            continue;
+        }
+        g_object_get(G_OBJECT(vm), "name", &name, NULL);
+        if (name == NULL) {
+            g_message("VM had no name in its XML description");
+            g_object_unref(vm);
+            continue;
+        }
+        if (g_hash_table_lookup(vms, name) != NULL) {
+            g_message("VM with the same name ('%s') already exists", name);
+            g_object_unref(vm);
+            continue;
+        }
+        g_hash_table_insert(vms, name, vm);
+    }
+    rest_xml_node_unref(root);
+    g_object_unref(G_OBJECT(parser));
+
+    return vms;
+}
+
+static gboolean ovirt_proxy_fetch_vms(OvirtProxy *proxy, GError **error)
+{
+    RestProxyCall *call;
+
+    g_return_val_if_fail(OVIRT_IS_PROXY(proxy), FALSE);
+    g_return_val_if_fail(REST_IS_PROXY(proxy->priv->rest_proxy), FALSE);
+
+    call = REST_PROXY_CALL(ovirt_rest_call_new(proxy->priv->rest_proxy));
+    rest_proxy_call_set_function(call, "vms");
+
+    if (!rest_proxy_call_sync(call, error)) {
+        g_warning("Error while getting VM list");
+        g_object_unref(G_OBJECT(call));
+        return FALSE;
+    }
+
+    proxy->priv->vms = parse_vms_xml(call);
+
+    g_object_unref(G_OBJECT(call));
+
+    return TRUE;
+}
+
+OvirtVm *ovirt_proxy_lookup_vm(OvirtProxy *proxy, const char *vm_name,
+                               GError **error)
+{
+    OvirtVm *vm;
+
+    g_return_val_if_fail(OVIRT_IS_PROXY(proxy), NULL);
+    g_return_val_if_fail(vm_name != NULL, NULL);
+
+    if (proxy->priv->vms == NULL) {
+        gboolean success;
+        success = ovirt_proxy_fetch_vms(proxy, error);
+        if (!success)
+            return NULL;
+    }
+    if (proxy->priv->vms == NULL) {
+        return NULL;
+    }
+
+    vm = g_hash_table_lookup(proxy->priv->vms, vm_name);
+
+    if (vm == NULL) {
+        return NULL;
+    }
+
+    return g_object_ref(vm);
+}
+
+static void parse_ticket_status(RestXmlNode *root, OvirtVm *vm, GError **error)
+{
+    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;
+
+    g_return_if_fail(root != NULL);
+    g_return_if_fail(vm != NULL);
+    g_return_if_fail(error == NULL || *error == NULL);
+
+    root = g_hash_table_lookup(root->children, ticket_key);
+    if (root == NULL) {
+        g_return_if_reached();
+    }
+    node = g_hash_table_lookup(root->children, value_key);
+    if (node == NULL) {
+        g_return_if_reached();
+    }
+
+    g_object_get(G_OBJECT(vm), "display", &display, NULL);
+    g_return_if_fail(display != NULL);
+    g_object_set(G_OBJECT(display), "ticket", node->content, NULL);
+
+    g_debug("Ticket: %s\n", node->content);
+
+    node = g_hash_table_lookup(root->children, expiry_key);
+    if (node == NULL) {
+        g_object_unref(G_OBJECT(display));
+        g_return_if_reached();
+    }
+    g_object_set(G_OBJECT(display),
+                 "expiry", strtoul(node->content, NULL, 0),
+                 NULL);
+    g_object_unref(G_OBJECT(display));
+}
+
+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_return_val_if_reached(OVIRT_RESPONSE_UNKNOWN);
+    }
+    node = g_hash_table_lookup(node->children, state_key);
+    if (node == NULL) {
+        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) {
+        return OVIRT_RESPONSE_PENDING;
+    } else if (g_strcmp0(node->content, "in_progress") == 0) {
+        return OVIRT_RESPONSE_IN_PROGRESS;
+    } else if (g_strcmp0(node->content, "failed") == 0) {
+        return OVIRT_RESPONSE_FAILED;
+    }
+
+    g_return_val_if_reached(OVIRT_RESPONSE_UNKNOWN);
+}
+
+static void parse_fault(RestXmlNode *root, GError **error)
+{
+    RestXmlNode *node;
+    const char *reason_key = g_intern_string("reason");
+    const char *detail_key = g_intern_string("detail");
+
+    g_return_if_fail(g_strcmp0(root->name, "fault") == 0);
+
+    node = g_hash_table_lookup(root->children, reason_key);
+    if (node == NULL) {
+        g_return_if_reached();
+    }
+    g_debug("Reason: %s\n", node->content);
+    node = g_hash_table_lookup(root->children, detail_key);
+    if (node == NULL) {
+        g_return_if_reached();
+    }
+    g_debug("Detail: %s\n", node->content);
+}
+
+static void parse_action_response(RestProxyCall *call, OvirtVm *vm, GError **error)
+{
+    RestXmlParser *parser;
+    RestXmlNode *root;
+
+    parser = rest_xml_parser_new ();
+
+    root = rest_xml_parser_parse_from_data (parser,
+            rest_proxy_call_get_payload (call),
+            rest_proxy_call_get_payload_length (call));
+
+    if (g_strcmp0(root->name, "action") == 0) {
+        if (parse_action_status(root, error) == OVIRT_RESPONSE_COMPLETE) {
+            parse_ticket_status(root, vm, error);
+        }
+    } else if (g_strcmp0(root->name, "fault") == 0) {
+        parse_fault(root, error);
+    } else {
+        g_warn_if_reached();
+    }
+
+    rest_xml_node_unref(root);
+    g_object_unref(G_OBJECT(parser));
+}
+
+
+static gboolean ovirt_proxy_vm_action(OvirtProxy *proxy, OvirtVm *vm,
+                                      const char *action, GError **error)
+{
+    RestProxyCall *call;
+    const char *function;
+
+    g_return_val_if_fail(OVIRT_IS_VM(vm), FALSE);
+    g_return_val_if_fail(action != NULL, FALSE);
+    g_return_val_if_fail(OVIRT_IS_PROXY(proxy), FALSE);
+    g_return_val_if_fail(REST_IS_PROXY(proxy->priv->rest_proxy), FALSE);
+    g_return_val_if_fail((error == NULL) || (*error == NULL), FALSE);
+
+    function = ovirt_vm_get_action(vm, action);
+    g_return_val_if_fail(function != NULL, FALSE);
+
+    call = REST_PROXY_CALL(ovirt_rest_call_new(proxy->priv->rest_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)) {
+        g_warning("Error while running %s on %p", action, vm);
+        parse_action_response(call, vm, NULL);
+        g_object_unref(G_OBJECT(call));
+        return FALSE;
+    }
+
+    parse_action_response(call, vm, NULL);
+
+    g_object_unref(G_OBJECT(call));
+
+    return TRUE;
+}
+
+gboolean ovirt_proxy_vm_get_ticket(OvirtProxy *proxy, OvirtVm *vm, GError **error)
+{
+    return ovirt_proxy_vm_action(proxy, vm, "ticket", error);
+}
+
+gboolean ovirt_proxy_vm_start(OvirtProxy *proxy, OvirtVm *vm, GError **error)
+{
+    return ovirt_proxy_vm_action(proxy, vm, "start", error);
+}
+
+gboolean ovirt_proxy_vm_stop(OvirtProxy *proxy, OvirtVm *vm, GError **error)
+{
+    return ovirt_proxy_vm_action(proxy, vm, "stop", error);
+}
+
+static void
+ovirt_get_property(GObject *object, guint property_id,
+                   GValue *value, GParamSpec *pspec)
+{
+    OvirtProxy *self = OVIRT_PROXY(object);
+
+    switch (property_id) {
+    case PROP_URI: {
+        char *uri;
+        g_object_get(G_OBJECT(self->priv->rest_proxy),
+                     "url-format", &uri,
+                     NULL);
+        g_value_take_string(value, uri);
+        break;
+    }
+
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+    }
+}
+
+static void
+ovirt_set_property(GObject *object, guint property_id,
+                   const GValue *value G_GNUC_UNUSED, GParamSpec *pspec)
+{
+    OvirtProxy *self = OVIRT_PROXY(object);
+
+    switch (property_id) {
+    case PROP_URI:
+        if (self->priv->rest_proxy)
+            g_object_unref(self->priv->rest_proxy);
+        self->priv->rest_proxy = rest_proxy_new_with_authentication(g_value_get_string(value),
+                                                                    FALSE,
+                                                                    ADMIN_LOGIN,
+                                                                    ADMIN_PASSWORD);
+        break;
+
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+    }
+}
+
+
+static void
+ovirt_proxy_dispose(GObject *obj)
+{
+    OvirtProxy *proxy = OVIRT_PROXY(obj);
+
+    g_clear_object(&proxy->priv->rest_proxy);
+    if (proxy->priv->vms) {
+        g_hash_table_unref(proxy->priv->vms);
+        proxy->priv->vms = NULL;
+    }
+
+    G_OBJECT_CLASS(ovirt_proxy_parent_class)->dispose(obj);
+}
+
+static void
+ovirt_proxy_class_init(OvirtProxyClass *klass)
+{
+    GObjectClass *oclass = G_OBJECT_CLASS(klass);
+
+    oclass->dispose = ovirt_proxy_dispose;
+    oclass->get_property = ovirt_get_property;
+    oclass->set_property = ovirt_set_property;
+
+    g_type_class_add_private(klass, sizeof(OvirtProxyPrivate));
+
+    g_object_class_install_property(oclass,
+                                    PROP_URI,
+                                    g_param_spec_string("uri",
+                                                        "REST URI",
+                                                        "REST URI",
+                                                        NULL,
+                                                        G_PARAM_READWRITE |
+                                                        G_PARAM_CONSTRUCT_ONLY |
+                                                        G_PARAM_STATIC_STRINGS));
+}
+
+static void
+ovirt_proxy_init(OvirtProxy *self)
+{
+    self->priv = OVIRT_PROXY_GET_PRIVATE(self);
+}
+
+OvirtProxy *ovirt_proxy_new(const char *uri)
+{
+    return g_object_new(OVIRT_TYPE_PROXY, "uri", uri, NULL);
+}
diff --git a/src/ovirt-proxy.h b/src/ovirt-proxy.h
new file mode 100644
index 0000000..18197a0
--- /dev/null
+++ b/src/ovirt-proxy.h
@@ -0,0 +1,70 @@
+/*
+ * ovirt-proxy.h: oVirt proxy using the oVirt REST API
+ *
+ * Copyright (C) 2012 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ *
+ * Author: Christophe Fergeau <cfergeau at redhat.com>
+ */
+#ifndef __OVIRT_PROXY_H__
+#define __OVIRT_PROXY_H__
+
+#include <glib-object.h>
+#include <ovirt-vm.h>
+
+G_BEGIN_DECLS
+
+#define OVIRT_TYPE_PROXY ovirt_proxy_get_type()
+
+#define OVIRT_PROXY(obj) \
+    (G_TYPE_CHECK_INSTANCE_CAST ((obj), OVIRT_TYPE_PROXY, OvirtProxy))
+
+#define OVIRT_PROXY_CLASS(klass) \
+    (G_TYPE_CHECK_CLASS_CAST ((klass), OVIRT_TYPE_PROXY, OvirtProxyClass))
+
+#define OVIRT_IS_PROXY(obj) \
+    (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OVIRT_TYPE_PROXY))
+
+#define OVIRT_IS_PROXY_CLASS(klass) \
+    (G_TYPE_CHECK_CLASS_TYPE ((klass), OVIRT_TYPE_PROXY))
+
+#define OVIRT_PROXY_GET_CLASS(obj) \
+    (G_TYPE_INSTANCE_GET_CLASS ((obj), OVIRT_TYPE_PROXY, OvirtProxyClass))
+
+typedef struct _OvirtProxy OvirtProxy;
+typedef struct _OvirtProxyClass OvirtProxyClass;
+typedef struct _OvirtProxyPrivate OvirtProxyPrivate;
+
+struct _OvirtProxy {
+    GObject parent;
+
+    OvirtProxyPrivate *priv;
+};
+
+struct _OvirtProxyClass {
+    GObjectClass parent_class;
+};
+
+GType ovirt_proxy_get_type(void);
+
+OvirtProxy *ovirt_proxy_new(const char *uri);
+OvirtVm *ovirt_proxy_lookup_vm(OvirtProxy *proxy, const char *vm_name,
+                               GError **error);
+gboolean ovirt_proxy_vm_get_ticket(OvirtProxy *proxy, OvirtVm *vm, GError **error);
+gboolean ovirt_proxy_vm_start(OvirtProxy *proxy, OvirtVm *vm, GError **error);
+gboolean ovirt_proxy_vm_stop(OvirtProxy *proxy, OvirtVm *vm, GError **error);
+
+#endif
-- 
1.7.10.2




More information about the virt-tools-list mailing list