[virt-tools-list] [[virt-viewer PATCHv3]] Add oVirt support
Christophe Fergeau
cfergeau at redhat.com
Mon Mar 11 08:46:06 UTC 2013
Ping?
On Thu, Feb 21, 2013 at 06:10:48PM +0100, Christophe Fergeau wrote:
> This commit adds support for ovirt:// URIs. It does so by using
> libgovirt to get the spice/vnc connection information through
> oVirt xmlrpc API.
> ---
> configure.ac | 18 ++++
> src/Makefile.am | 8 ++
> src/remote-viewer.c | 230 +++++++++++++++++++++++++++++++++++++++++++++++++++-
> virt-viewer.spec.in | 11 ++-
> 4 files changed, 262 insertions(+), 5 deletions(-)
>
> diff --git a/configure.ac b/configure.ac
> index 30c2042..bbd9114 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -165,6 +165,22 @@ AS_IF([test "x$have_spice_gtk" = "xyes"],
> ])
> AM_CONDITIONAL([HAVE_SPICE_GTK], [test "x$have_spice_gtk" = "xyes"])
>
> +AC_ARG_WITH([ovirt],
> + AS_HELP_STRING([--without-ovirt], [Ignore presence of librest and disable oVirt support]))
> +
> +AS_IF([test "x$with_ovirt" != "xno"],
> + [PKG_CHECK_MODULES([OVIRT], [govirt-1.0],
> + [have_ovirt=yes], [have_ovirt=no])],
> + [have_ovirt=no])
> +
> +AS_IF([test "x$have_ovirt" = "xyes"],
> + [AC_DEFINE([HAVE_OVIRT], 1, [Have libgovirt?])],
> + [AS_IF([test "x$with_ovirt" = "xyes"],
> + [AC_MSG_ERROR([oVirt support requested but libgovirt not found])
> + ])
> +])
> +AM_CONDITIONAL([HAVE_OVIRT], [test "x$have_ovirt" = "xyes"])
> +
> dnl Decide if this platform can support the SSH tunnel feature.
> AC_CHECK_HEADERS([sys/socket.h sys/un.h windows.h])
> AC_CHECK_FUNCS([fork socketpair])
> @@ -241,3 +257,5 @@ AC_MSG_NOTICE([ LIBXML2: $LIBXML2_CFLAGS $LIBXML2_LIBS])
> AC_MSG_NOTICE([])
> AC_MSG_NOTICE([ LIBVIRT: $LIBVIRT_CFLAGS $LIBVIRT_LIBS])
> AC_MSG_NOTICE([])
> +AC_MSG_NOTICE([ OVIRT: $OVIRT_CFLAGS $OVIRT_LIBS])
> +AC_MSG_NOTICE([])
> diff --git a/src/Makefile.am b/src/Makefile.am
> index 05e20b2..f929aa5 100644
> --- a/src/Makefile.am
> +++ b/src/Makefile.am
> @@ -96,6 +96,10 @@ if HAVE_GTK_VNC
> virt_viewer_LDFLAGS += $(GTK_VNC_LIBS)
> virt_viewer_CFLAGS += $(GTK_VNC_CFLAGS)
> endif
> +if HAVE_OVIRT
> +virt_viewer_LDFLAGS += $(OVIRT_LIBS)
> +virt_viewer_CFLAGS += $(OVIRT_CFLAGS)
> +endif
> if HAVE_SPICE_GTK
> virt_viewer_LDFLAGS += $(SPICE_GTK_LIBS)
> virt_viewer_CFLAGS += $(SPICE_GTK_CFLAGS)
> @@ -128,6 +132,10 @@ if HAVE_GTK_VNC
> remote_viewer_LDFLAGS += $(GTK_VNC_LIBS)
> remote_viewer_CFLAGS += $(GTK_VNC_CFLAGS)
> endif
> +if HAVE_OVIRT
> +remote_viewer_LDFLAGS += $(OVIRT_LIBS)
> +remote_viewer_CFLAGS += $(OVIRT_CFLAGS)
> +endif
> if HAVE_SPICE_GTK
> remote_viewer_LDFLAGS += $(SPICE_GTK_LIBS) $(SPICE_CONTROLLER_LIBS)
> remote_viewer_CFLAGS += $(SPICE_GTK_CFLAGS) $(SPICE_CONTROLLER_CFLAGS)
> diff --git a/src/remote-viewer.c b/src/remote-viewer.c
> index fa17edd..f2a5648 100644
> --- a/src/remote-viewer.c
> +++ b/src/remote-viewer.c
> @@ -26,6 +26,11 @@
> #include <gtk/gtk.h>
> #include <glib/gprintf.h>
> #include <glib/gi18n.h>
> +#include <libxml/uri.h>
> +
> +#ifdef HAVE_OVIRT
> +#include <govirt/govirt.h>
> +#endif
>
> #ifdef HAVE_SPICE_GTK
> #include <spice-controller.h>
> @@ -35,6 +40,7 @@
> #include "virt-viewer-session-spice.h"
> #endif
> #include "virt-viewer-app.h"
> +#include "virt-viewer-auth.h"
> #include "virt-viewer-file.h"
> #include "virt-viewer-session.h"
> #include "remote-viewer.h"
> @@ -585,6 +591,213 @@ remote_viewer_window_added(VirtViewerApp *app G_GNUC_UNUSED,
> }
> #endif
>
> +#ifdef HAVE_OVIRT
> +static gboolean
> +parse_ovirt_uri(const gchar *uri_str, char **rest_uri, char **name)
> +{
> + char *vm_name = NULL;
> + char *rel_path;
> + xmlURIPtr uri;
> + gchar **path_elements;
> + guint element_count;
> +
> + g_return_val_if_fail(uri_str != NULL, FALSE);
> + g_return_val_if_fail(rest_uri != NULL, FALSE);
> + g_return_val_if_fail(name != NULL, FALSE);
> +
> + uri = xmlParseURI(uri_str);
> + if (uri == NULL)
> + return FALSE;
> +
> + if (g_strcmp0(uri->scheme, "ovirt") != 0) {
> + xmlFreeURI(uri);
> + return FALSE;
> + }
> +
> + if (uri->path == NULL) {
> + xmlFreeURI(uri);
> + return FALSE;
> + }
> +
> + /* extract VM name from path */
> + path_elements = g_strsplit(uri->path, "/", -1);
> +
> + element_count = g_strv_length(path_elements);
> + if (element_count == 0) {
> + g_strfreev(path_elements);
> + xmlFreeURI(uri);
> + return FALSE;
> + }
> + vm_name = path_elements[element_count-1];
> + path_elements[element_count-1] = NULL;
> +
> + /* build final URI */
> + rel_path = g_strjoinv("/", path_elements);
> + /* FIXME: how to decide between http and https? */
> + *rest_uri = g_strdup_printf("https://%s/%s/api/", uri->server, rel_path);
> + *name = vm_name;
> + g_free(rel_path);
> + g_strfreev(path_elements);
> + xmlFreeURI(uri);
> +
> + g_debug("oVirt base URI: %s", *rest_uri);
> + g_debug("oVirt VM name: %s", *name);
> +
> + return TRUE;
> +}
> +
> +static gboolean
> +authenticate_cb(RestProxy *proxy, G_GNUC_UNUSED RestProxyAuth *auth,
> + G_GNUC_UNUSED gboolean retrying, gpointer user_data)
> +{
> + gchar *username;
> + gchar *password;
> + VirtViewerWindow *window;
> +
> + window = virt_viewer_app_get_main_window(VIRT_VIEWER_APP(user_data));
> + int ret = virt_viewer_auth_collect_credentials(virt_viewer_window_get_window(window),
> + "oVirt",
> + NULL,
> + &username, &password);
> + if (ret < 0) {
> + return FALSE;
> + } else {
> + g_object_set(G_OBJECT(proxy),
> + "username", username,
> + "password", password,
> + NULL);
> + g_free(username);
> + g_free(password);
> + return TRUE;
> + }
> +}
> +
> +
> +static gboolean
> +create_ovirt_session(VirtViewerApp *app, const char *uri)
> +{
> + OvirtProxy *proxy = NULL;
> + OvirtVm *vm = NULL;
> + OvirtVmDisplay *display = NULL;
> + OvirtVmState state;
> + GError *error = NULL;
> + char *rest_uri = NULL;
> + char *vm_name = NULL;
> + gboolean success = FALSE;
> + guint port;
> + guint secure_port;
> + OvirtVmDisplayType type;
> + const char *session_type;
> +
> + gchar *gport = NULL;
> + gchar *gtlsport = NULL;
> + gchar *ghost = NULL;
> + gchar *ticket = NULL;
> +
> + g_return_val_if_fail(VIRT_VIEWER_IS_APP(app), FALSE);
> +
> + if (!parse_ovirt_uri(uri, &rest_uri, &vm_name))
> + goto error;
> + proxy = ovirt_proxy_new(rest_uri);
> + if (proxy == NULL)
> + goto error;
> + g_signal_connect(G_OBJECT(proxy), "authenticate",
> + G_CALLBACK(authenticate_cb), app);
> +
> + ovirt_proxy_fetch_ca_certificate(proxy, &error);
> + if (error != NULL) {
> + g_debug("failed to get CA certificate: %s", error->message);
> + goto error;
> + }
> +
> + ovirt_proxy_fetch_vms(proxy, &error);
> + if (error != NULL) {
> + g_debug("failed to lookup %s: %s", vm_name, error->message);
> + goto error;
> + }
> +
> + vm = ovirt_proxy_lookup_vm(proxy, vm_name);
> + g_return_val_if_fail(vm != NULL, FALSE);
> + g_object_get(G_OBJECT(vm), "state", &state, NULL);
> + if (state != OVIRT_VM_STATE_UP) {
> + g_debug("oVirt VM %s is not running", vm_name);
> + goto error;
> + }
> +
> + if (!ovirt_vm_get_ticket(vm, proxy, &error)) {
> + g_debug("failed to get ticket for %s: %s", vm_name, error->message);
> + goto error;
> + }
> +
> + g_object_get(G_OBJECT(vm), "display", &display, NULL);
> + if (display == NULL) {
> + goto error;
> + }
> +
> + g_object_get(G_OBJECT(display),
> + "type", &type,
> + "address", &ghost,
> + "port", &port,
> + "secure-port", &secure_port,
> + "ticket", &ticket,
> + NULL);
> + gport = g_strdup_printf("%d", port);
> + gtlsport = g_strdup_printf("%d", secure_port);
> +
> + if (type == OVIRT_VM_DISPLAY_SPICE) {
> + session_type = "spice";
> + } else if (type == OVIRT_VM_DISPLAY_VNC) {
> + session_type = "vnc";
> + } else {
> + g_debug("Unknown display type: %d", type);
> + goto error;
> + }
> +
> + virt_viewer_app_set_connect_info(app, NULL, ghost, gport, gtlsport,
> + session_type, NULL, NULL, 0, NULL);
> +
> + if (virt_viewer_app_create_session(app, session_type) < 0)
> + goto error;
> +
> +#if HAVE_SPICE_GTK
> + if (type == OVIRT_VM_DISPLAY_SPICE) {
> + SpiceSession *session;
> + GByteArray *ca_cert;
> +
> + g_object_get(G_OBJECT(proxy), "ca-cert", &ca_cert, NULL);
> + session = remote_viewer_get_spice_session(REMOTE_VIEWER(app));
> + g_object_set(G_OBJECT(session),
> + "ca", ca_cert,
> + "password", ticket,
> + NULL);
> + g_byte_array_unref(ca_cert);
> + }
> +#endif
> +
> + success = TRUE;
> +
> +error:
> + g_free(rest_uri);
> + g_free(vm_name);
> + g_free(ticket);
> + g_free(gport);
> + g_free(gtlsport);
> + g_free(ghost);
> +
> + if (error != NULL)
> + g_error_free(error);
> + if (display != NULL)
> + g_object_unref(display);
> + if (vm != NULL)
> + g_object_unref(vm);
> + if (proxy != NULL)
> + g_object_unref(proxy);
> +
> + return success;
> +}
> +
> +#endif
> +
> static gboolean
> remote_viewer_start(VirtViewerApp *app)
> {
> @@ -646,10 +859,19 @@ remote_viewer_start(VirtViewerApp *app)
> virt_viewer_app_simple_message_dialog(app, _("Cannot determine the connection type from URI"));
> goto cleanup;
> }
> -
> - if (virt_viewer_app_create_session(app, type) < 0) {
> - virt_viewer_app_simple_message_dialog(app, _("Couldn't create a session for this type: %s"), type);
> - goto cleanup;
> +#if HAVE_OVIRT
> + if (g_strcmp0(type, "ovirt") == 0) {
> + if (!create_ovirt_session(app, guri)) {
> + virt_viewer_app_simple_message_dialog(app, _("Couldn't open oVirt session"));
> + goto cleanup;
> + }
> + } else
> +#endif
> + {
> + if (virt_viewer_app_create_session(app, type) < 0) {
> + virt_viewer_app_simple_message_dialog(app, _("Couldn't create a session for this type: %s"), type);
> + goto cleanup;
> + }
> }
>
> virt_viewer_session_set_file(virt_viewer_app_get_session(app), vvfile);
> diff --git a/virt-viewer.spec.in b/virt-viewer.spec.in
> index ee91b5f..122d768 100644
> --- a/virt-viewer.spec.in
> +++ b/virt-viewer.spec.in
> @@ -19,6 +19,8 @@
> %define with_spice 1
> %endif
>
> +%define with_govirt 0
> +
> %if 0%{?rhel} >= 6
> %define with_spice 1
> %endif
> @@ -80,6 +82,9 @@ BuildRequires: xulrunner-devel
> BuildRequires: firefox-devel
> %endif
> %endif
> +%if %{with_govirt}
> +BuildRequires: libgovirt-devel >= 0.0.3
> +%endif
>
> %description
> Virtual Machine Viewer provides a graphical console client for connecting
> @@ -128,7 +133,11 @@ autoreconf -if
> %define gtk_arg --with-gtk=2.0
> %endif
>
> -%configure %{spice_arg} %{plugin_arg} %{gtk_arg}
> +%if %{with_govirt}
> +%define govirt_arg --with-ovirt
> +%endif
> +
> +%configure %{spice_arg} %{plugin_arg} %{gtk_arg} %{govirt_arg}
> %__make %{?_smp_mflags}
>
>
> --
> 1.8.1.2
>
> _______________________________________________
> virt-tools-list mailing list
> virt-tools-list at redhat.com
> https://www.redhat.com/mailman/listinfo/virt-tools-list
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://listman.redhat.com/archives/virt-tools-list/attachments/20130311/db715fbb/attachment.sig>
More information about the virt-tools-list
mailing list