Support for virDomainOpenGraphics API

Add a new flag --attach, which instructs virt-viewer to attach
to the target display using virDomainOpenGraphics, instead of
initiating a VNC/SPICE connection directly.
This commit is contained in:
Daniel P. Berrange 2011-10-21 13:57:11 +01:00
parent a94100eaeb
commit 5bc4c0b342
5 changed files with 121 additions and 6 deletions

View File

@ -111,6 +111,7 @@ struct _VirtViewerAppPrivate {
gboolean authretry;
gboolean started;
gboolean fullscreen;
gboolean attach;
VirtViewerSession *session;
gboolean active;
@ -650,6 +651,26 @@ virt_viewer_app_create_session(VirtViewerApp *self, const gchar *type)
return 0;
}
static gboolean
virt_viewer_app_default_open_connection(VirtViewerApp *self G_GNUC_UNUSED, int *fd)
{
*fd = -1;
return TRUE;
}
static int
virt_viewer_app_open_connection(VirtViewerApp *self, int *fd)
{
VirtViewerAppClass *klass;
g_return_val_if_fail(VIRT_VIEWER_IS_APP(self), -1);
klass = VIRT_VIEWER_APP_GET_CLASS(self);
return klass->open_connection(self, fd);
}
#if defined(HAVE_SOCKETPAIR) && defined(HAVE_FORK)
static void
virt_viewer_app_channel_open(VirtViewerSession *session,
@ -661,13 +682,18 @@ virt_viewer_app_channel_open(VirtViewerSession *session,
g_return_if_fail(self != NULL);
if (!virt_viewer_app_open_connection(self, &fd))
return;
DEBUG_LOG("After open connection callback fd=%d", fd);
priv = self->priv;
if (priv->transport && g_ascii_strcasecmp(priv->transport, "ssh") == 0 &&
!priv->direct) {
!priv->direct && fd == -1) {
if ((fd = virt_viewer_app_open_tunnel_ssh(priv->host, priv->port, priv->user,
priv->ghost, priv->gport, NULL)) < 0)
virt_viewer_app_simple_message_dialog(self, _("Connect to ssh failed."));
} else {
} else if (fd == -1) {
virt_viewer_app_simple_message_dialog(self, _("Can't connect to channel, SSH only supported."));
}
@ -690,10 +716,16 @@ virt_viewer_app_default_activate(VirtViewerApp *self)
VirtViewerAppPrivate *priv = self->priv;
int fd = -1;
if (!virt_viewer_app_open_connection(self, &fd))
return -1;
DEBUG_LOG("After open connection callback fd=%d", fd);
#if defined(HAVE_SOCKETPAIR) && defined(HAVE_FORK)
if (priv->transport &&
g_ascii_strcasecmp(priv->transport, "ssh") == 0 &&
!priv->direct) {
!priv->direct &&
fd == -1) {
gchar *p = NULL;
if (priv->gport) {
@ -716,7 +748,7 @@ virt_viewer_app_default_activate(VirtViewerApp *self)
priv->user, priv->ghost,
priv->gport, priv->unixsock)) < 0)
return -1;
} else if (priv->unixsock) {
} else if (priv->unixsock && fd == -1) {
virt_viewer_app_trace(self, "Opening direct UNIX connection to display at %s",
priv->unixsock);
if ((fd = virt_viewer_app_open_unix_sock(priv->unixsock)) < 0)
@ -1190,6 +1222,7 @@ virt_viewer_app_class_init (VirtViewerAppClass *klass)
klass->initial_connect = virt_viewer_app_default_initial_connect;
klass->activate = virt_viewer_app_default_activate;
klass->deactivated = virt_viewer_app_default_deactivated;
klass->open_connection = virt_viewer_app_default_open_connection;
g_object_class_install_property(object_class,
PROP_VERBOSE,
@ -1292,6 +1325,22 @@ virt_viewer_app_set_direct(VirtViewerApp *self, gboolean direct)
self->priv->direct = direct;
}
void
virt_viewer_app_set_attach(VirtViewerApp *self, gboolean attach)
{
g_return_if_fail(VIRT_VIEWER_IS_APP(self));
self->priv->attach = attach;
}
gboolean
virt_viewer_app_get_attach(VirtViewerApp *self)
{
g_return_val_if_fail(VIRT_VIEWER_IS_APP(self), FALSE);
return self->priv->attach;
}
gboolean
virt_viewer_app_is_active(VirtViewerApp *self)
{

View File

@ -55,6 +55,7 @@ typedef struct {
int (*initial_connect) (VirtViewerApp *self);
int (*activate) (VirtViewerApp *self);
void (*deactivated) (VirtViewerApp *self);
gboolean (*open_connection)(VirtViewerApp *self, int *fd);
} VirtViewerAppClass;
GType virt_viewer_app_get_type (void);
@ -73,6 +74,8 @@ int virt_viewer_app_initial_connect(VirtViewerApp *self);
void virt_viewer_app_start_reconnect_poll(VirtViewerApp *self);
void virt_viewer_app_set_zoom_level(VirtViewerApp *self, gint zoom_level);
void virt_viewer_app_set_direct(VirtViewerApp *self, gboolean direct);
void virt_viewer_app_set_attach(VirtViewerApp *self, gboolean attach);
gboolean virt_viewer_app_get_attach(VirtViewerApp *self);
gboolean virt_viewer_app_has_session(VirtViewerApp *self);
void virt_viewer_app_set_connect_info(VirtViewerApp *self,
const gchar *host,

View File

@ -52,6 +52,7 @@ int main(int argc, char **argv)
gboolean verbose = FALSE;
gboolean debug = FALSE;
gboolean direct = FALSE;
gboolean attach = FALSE;
gboolean waitvm = FALSE;
gboolean reconnect = FALSE;
gboolean fullscreen = FALSE;
@ -64,6 +65,8 @@ int main(int argc, char **argv)
N_("Display verbose information"), NULL },
{ "direct", 'd', 0, G_OPTION_ARG_NONE, &direct,
N_("Direct connection with no automatic tunnels"), NULL },
{ "attach", 'a', 0, G_OPTION_ARG_NONE, &attach,
N_("Attach to the local display using libvirt"), NULL },
{ "connect", 'c', 0, G_OPTION_ARG_STRING, &uri,
N_("Connect to hypervisor"), "URI"},
{ "wait", 'w', 0, G_OPTION_ARG_NONE, &waitvm,
@ -121,7 +124,7 @@ int main(int argc, char **argv)
virt_viewer_app_set_debug(debug);
viewer = virt_viewer_new(uri, args[0], zoom, direct, waitvm, reconnect, verbose, NULL);
viewer = virt_viewer_new(uri, args[0], zoom, direct, attach, waitvm, reconnect, verbose, NULL);
if (viewer == NULL)
goto cleanup;

View File

@ -40,6 +40,10 @@
#include <libxml/xpath.h>
#include <libxml/uri.h>
#if defined(HAVE_SOCKETPAIR)
#include <sys/socket.h>
#endif
#include "virt-viewer.h"
#include "virt-viewer-app.h"
#include "virt-viewer-events.h"
@ -48,6 +52,7 @@
struct _VirtViewerPrivate {
char *uri;
virConnectPtr conn;
virDomainPtr dom;
char *domkey;
gboolean withEvents;
gboolean waitvm;
@ -59,6 +64,7 @@ G_DEFINE_TYPE (VirtViewer, virt_viewer, VIRT_VIEWER_TYPE_APP)
(G_TYPE_INSTANCE_GET_PRIVATE ((o), VIRT_VIEWER_TYPE, VirtViewerPrivate))
static int virt_viewer_initial_connect(VirtViewerApp *self);
static gboolean virt_viewer_open_connection(VirtViewerApp *self, int *fd);
static void virt_viewer_deactivated(VirtViewerApp *self);
static gboolean virt_viewer_start(VirtViewerApp *self);
@ -85,6 +91,12 @@ virt_viewer_set_property (GObject *object, guint property_id,
static void
virt_viewer_dispose (GObject *object)
{
VirtViewer *self = VIRT_VIEWER(object);
VirtViewerPrivate *priv = self->priv;
if (priv->dom)
virDomainFree(priv->dom);
if (priv->conn)
virConnectClose(priv->conn);
G_OBJECT_CLASS(virt_viewer_parent_class)->dispose (object);
}
@ -102,6 +114,7 @@ virt_viewer_class_init (VirtViewerClass *klass)
app_class->initial_connect = virt_viewer_initial_connect;
app_class->deactivated = virt_viewer_deactivated;
app_class->open_connection = virt_viewer_open_connection;
app_class->start = virt_viewer_start;
}
@ -117,6 +130,11 @@ virt_viewer_deactivated(VirtViewerApp *app)
VirtViewer *self = VIRT_VIEWER(app);
VirtViewerPrivate *priv = self->priv;
if (priv->dom) {
virDomainFree(priv->dom);
priv->dom = NULL;
}
if (priv->reconnect) {
if (!priv->withEvents) {
DEBUG_LOG("No domain events, falling back to polling");
@ -365,6 +383,11 @@ virt_viewer_update_display(VirtViewer *self, virDomainPtr dom)
VirtViewerPrivate *priv = self->priv;
VirtViewerApp *app = VIRT_VIEWER_APP(self);
if (priv->dom)
virDomainFree(priv->dom);
priv->dom = dom;
virDomainRef(priv->dom);
virt_viewer_app_trace(app, "Guest %s is running, determining display\n",
priv->domkey);
@ -378,6 +401,36 @@ virt_viewer_update_display(VirtViewer *self, virDomainPtr dom)
return 0;
}
static gboolean
virt_viewer_open_connection(VirtViewerApp *self G_GNUC_UNUSED, int *fd)
{
#if defined(HAVE_SOCKETPAIR)
VirtViewer *viewer = VIRT_VIEWER(self);
VirtViewerPrivate *priv = viewer->priv;
int pair[2];
#endif
*fd = -1;
#if defined(HAVE_SOCKETPAIR)
if (!priv->dom)
return TRUE;
if (socketpair(PF_UNIX, SOCK_STREAM, 0, pair) < 0)
return FALSE;
if (virDomainOpenGraphics(priv->dom, 0, pair[0],
VIR_DOMAIN_OPEN_GRAPHICS_SKIPAUTH) < 0) {
virErrorPtr err = virGetLastError();
DEBUG_LOG("Error %s", err && err->message ? err->message : "Unknown");
close(pair[0]);
close(pair[1]);
return TRUE;
}
close(pair[0]);
*fd = pair[1];
#endif
return TRUE;
}
static int
virt_viewer_domain_event(virConnectPtr conn G_GNUC_UNUSED,
virDomainPtr dom,
@ -488,6 +541,10 @@ virt_viewer_start(VirtViewerApp *app)
.cb = virt_viewer_auth_libvirt_credentials,
.cbdata = (void *)priv->uri,
};
int oflags = 0;
if (!virt_viewer_app_get_attach(app))
oflags |= VIR_CONNECT_RO;
virt_viewer_events_register();
@ -498,7 +555,7 @@ virt_viewer_start(VirtViewerApp *app)
priv->conn = virConnectOpenAuth(priv->uri,
//virConnectAuthPtrDefault,
&auth_libvirt,
VIR_CONNECT_RO);
oflags);
if (!priv->conn) {
virt_viewer_app_simple_message_dialog(app, _("Unable to connect to libvirt with URI %s"),
priv->uri ? priv->uri : _("[none]"));
@ -530,6 +587,7 @@ virt_viewer_new(const char *uri,
const char *name,
gint zoom,
gboolean direct,
gboolean attach,
gboolean waitvm,
gboolean reconnect,
gboolean verbose,
@ -553,6 +611,7 @@ virt_viewer_new(const char *uri,
g_object_set(app, "title", name, NULL);
virt_viewer_window_set_zoom_level(virt_viewer_app_get_main_window(app), zoom);
virt_viewer_app_set_direct(app, direct);
virt_viewer_app_set_attach(app, attach);
/* should probably be properties instead */
priv->uri = g_strdup(uri);

View File

@ -53,6 +53,7 @@ virt_viewer_new(const char *uri,
const char *name,
gint zoom,
gboolean direct,
gboolean attach,
gboolean waitvm,
gboolean reconnect,
gboolean verbose,