--- src/virt-viewer-session-ovirt.c | 194 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 189 insertions(+), 5 deletions(-) diff --git a/src/virt-viewer-session-ovirt.c b/src/virt-viewer-session-ovirt.c index 3fc7c62..5b71c83 100644 --- a/src/virt-viewer-session-ovirt.c +++ b/src/virt-viewer-session-ovirt.c @@ -27,8 +27,11 @@ #include <glib/gi18n.h> #include "ovirt-proxy.h" -#include "virt-viewer-util.h" +#include "ovirt-vm.h" +#include "ovirt-vm-display.h" #include "virt-viewer-session-ovirt.h" +#include "virt-viewer-session-spice.h" +#include "virt-viewer-util.h" #if !GLIB_CHECK_VERSION(2, 26, 0) #include "gbinding.h" @@ -177,7 +180,7 @@ parse_uri(VirtViewerSession *session, const gchar *uri) tmp_uri = g_strndup(uri, pos - uri + 1); g_assert(g_str_has_prefix(tmp_uri, "ovirt://")); /* FIXME: how to decide between http and https? */ - self->priv->rest_uri = g_strdup_printf("http://%s/api/", + self->priv->rest_uri = g_strdup_printf("https://%s/api/", tmp_uri + strlen("ovirt://")); g_free(tmp_uri); self->priv->vm_name = g_strdup(vm_name); @@ -187,20 +190,201 @@ parse_uri(VirtViewerSession *session, const gchar *uri) return TRUE; } +static void +create_spice_session(VirtViewerSessionOvirt *ovirt, + const char *address, + guint16 port, guint16 secure_port, + const char *ticket) +{ + VirtViewerApp *app; + char *spice_uri; + + /* FIXME: escape & and ; in password */ + spice_uri = g_strdup_printf("spice://%s?password=%s", address, ticket); + if (secure_port != 0) { + char *tmp_uri; + tmp_uri = g_strdup_printf("%s&tls-port=%d", spice_uri, secure_port); + g_free(spice_uri); + spice_uri = tmp_uri; + } + if (port != 0) { + char *tmp_uri; + tmp_uri = g_strdup_printf("%s&port=%d", spice_uri, port); + g_free(spice_uri); + spice_uri = tmp_uri; + } + g_debug("spice URI: %s", spice_uri); + + g_object_get(ovirt, "app", &app, NULL); + ovirt->priv->real_session = virt_viewer_session_spice_new(app, ovirt->priv->main_window); + g_object_unref(app); + + virt_viewer_session_open_uri(ovirt->priv->real_session, spice_uri); + g_free(spice_uri); +} + +static void +get_ticket_async_cb(OvirtProxy *proxy, OvirtVm *vm, + const GError *error, gpointer user_data) +{ + VirtViewerSessionOvirt *ovirt; + OvirtVmDisplay *display = NULL; + gchar *address = NULL; + guint port; + guint secure_port; + OvirtVmDisplayType type; + char *ticket = NULL;; + + ovirt = VIRT_VIEWER_SESSION_OVIRT(user_data); + if (error != NULL) { + g_debug("failed to get ticket for VM %s: %s", + ovirt->priv->vm_name, error->message); + goto end; + } + + g_object_get(G_OBJECT(vm), "display", &display, NULL); + if (display == NULL) { + goto end; + } + + g_object_get(G_OBJECT(display), + "type", &type, + "address", &address, + "port", &port, + "secure-port", &secure_port, + "ticket", &ticket, + NULL); + g_debug("Ticket: %s", ticket); + + if (type != OVIRT_VM_DISPLAY_SPICE) { + goto end; + } + + if ((port == 0) && (secure_port == 0)) { + goto end; + } + + create_spice_session(ovirt, address, port, secure_port, ticket); + +end: + g_free(address); + g_free(ticket); + if (display != NULL) { + g_object_unref(G_OBJECT(display)); + } + g_object_unref(G_OBJECT(proxy)); + g_object_unref(G_OBJECT(vm)); +} + +static void +start_vm_async_cb(OvirtProxy *proxy, OvirtVm *vm, + const GError *start_error, gpointer user_data) +{ + VirtViewerSessionOvirt *ovirt = VIRT_VIEWER_SESSION_OVIRT(user_data); + GError *error = NULL; + + ovirt = VIRT_VIEWER_SESSION_OVIRT(user_data); + if (start_error != NULL) { + g_debug("failed to start VM %s: %s", + ovirt->priv->vm_name, start_error->message); + goto error; + } + + if (!ovirt_proxy_vm_get_ticket_async(proxy, vm, get_ticket_async_cb, + ovirt, &error)) { + g_debug("failed to get ticket for VM %s: %s", + ovirt->priv->vm_name, error->message); + goto error; + } + return; + +error: + if (error != NULL) + g_error_free(error); + g_object_unref(G_OBJECT(proxy)); + g_object_unref(G_OBJECT(vm)); +} + +static void +lookup_vm_async_cb(OvirtProxy *proxy, OvirtVm *vm, + const GError *lookup_error, gpointer user_data) +{ + VirtViewerSessionOvirt *ovirt = VIRT_VIEWER_SESSION_OVIRT(user_data); + OvirtVmState state; + GError *error = NULL; + + if (vm == NULL) { + g_debug("%s could not be lookep up", ovirt->priv->vm_name); + } + g_object_ref(G_OBJECT(vm)); + if (lookup_error != NULL) { + g_debug("error looking up %s: %s", + ovirt->priv->vm_name, + lookup_error->message); + goto error; + } + + g_object_get(G_OBJECT(vm), "state", &state, NULL); + if (state != OVIRT_VM_STATE_UP) { + /* FIXME: should be async */ + ovirt_proxy_vm_start_async(proxy, vm, start_vm_async_cb, ovirt, &error); + if (error != NULL) { + g_debug("failed to start %s: %s", + ovirt->priv->vm_name, + error->message); + goto error; + } + } + + if (!ovirt_proxy_vm_get_ticket_async(proxy, vm, get_ticket_async_cb, + ovirt, &error)) { + g_debug("failed to get ticket for VM %s: %s", + ovirt->priv->vm_name, error->message); + goto error; + } + return; + +error: + if (vm != NULL) + g_object_unref(vm); + g_object_unref(proxy); + if (error != NULL) + g_error_free(error); +} + static gboolean virt_viewer_session_ovirt_open_uri(VirtViewerSession *session, const gchar *uri) { /* FIXME: resolve */ VirtViewerSessionOvirt *self = VIRT_VIEWER_SESSION_OVIRT(session); - OvirtProxy *proxy; + OvirtProxy *proxy = NULL; + GError *error = NULL; g_return_val_if_fail(self != NULL, FALSE); - g_warning("open_uri: %s", uri); if (!parse_uri(session, uri)) - return FALSE; + goto error; + g_debug("oVirt REST URI: %s", self->priv->rest_uri); + proxy = ovirt_proxy_new (self->priv->rest_uri); + if (proxy == NULL) + goto error; + ovirt_proxy_lookup_vm_async(proxy, self->priv->vm_name, + lookup_vm_async_cb, session, + &error); + if (error != NULL) { + g_debug("failed to lookup %s: %s", + self->priv->vm_name, + error->message); + goto error; + } + return TRUE; +error: + if (error != NULL) + g_error_free(error); + if (proxy != NULL) + g_object_unref(proxy); return FALSE; } -- 1.7.10.2