mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/virt-viewer
synced 2025-12-29 08:42:19 +00:00
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:
parent
a94100eaeb
commit
5bc4c0b342
@ -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)
|
||||
{
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user