On 05/13/2013 09:10 PM, Martin Kletzander wrote:
Adding a VNC WebSocket support for QEMU driver. This functionality
is
in upstream qemu from commit described as v1.3.0-982-g7536ee4, so the
capability is being recognized based on QEMU version for now.
Signed-off-by: Martin Kletzander <mkletzan(a)redhat.com>
---
src/qemu/libvirtd_qemu.aug | 2 +
src/qemu/qemu.conf | 6 +++
src/qemu/qemu_capabilities.c | 5 ++
src/qemu/qemu_capabilities.h | 1 +
src/qemu/qemu_command.c | 60 +++++++++++++++++++++-
src/qemu/qemu_command.h | 3 ++
src/qemu/qemu_conf.c | 32 ++++++++++++
src/qemu/qemu_conf.h | 6 +++
src/qemu/qemu_driver.c | 5 ++
src/qemu/qemu_process.c | 44 ++++++++++++----
src/qemu/test_libvirtd_qemu.aug.in | 2 +
tests/qemuargv2xmltest.c | 1 +
.../qemuxml2argv-graphics-vnc-websocket.args | 4 ++
.../qemuxml2argv-graphics-vnc-websocket.xml | 28 ++++++++++
tests/qemuxml2argvtest.c | 1 +
tests/qemuxml2xmltest.c | 1 +
16 files changed, 189 insertions(+), 12 deletions(-)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-websocket.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-websocket.xml
diff --git a/src/qemu/libvirtd_qemu.aug b/src/qemu/libvirtd_qemu.aug
index a3dcb30..5344125 100644
--- a/src/qemu/libvirtd_qemu.aug
+++ b/src/qemu/libvirtd_qemu.aug
@@ -41,6 +41,8 @@ module Libvirtd_qemu =
let remote_display_entry = int_entry "remote_display_port_min"
| int_entry "remote_display_port_max"
+ | int_entry "remote_websocket_port_min"
+ | int_entry "remote_websocket_port_max"
let security_entry = str_entry "security_driver"
| bool_entry "security_default_confined"
diff --git a/src/qemu/qemu.conf b/src/qemu/qemu.conf
index 0f0a24c..cdf1ec4 100644
--- a/src/qemu/qemu.conf
+++ b/src/qemu/qemu.conf
@@ -153,6 +153,12 @@
#remote_display_port_min = 5900
#remote_display_port_max = 65535
+# VNC WebSocket port policies, same rules apply as with remote display
+# ports. VNC WebSockets use similar display <-> port mappings, with
+# the exception being that ports starts from 5700 instead of 5900.
+#
+#remote_websocket_port_min = 5700
+#remote_websocket_port_max = 65535
# The default security driver is SELinux. If SELinux is disabled
# on the host, then the security driver will automatically disable
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 74ac43c..18ebe14 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -227,6 +227,7 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST,
"scsi-generic",
"scsi-generic.bootindex", /* 145 */
+ "vnc-websocket",
);
struct _virQEMUCaps {
@@ -2567,6 +2568,10 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
if (qemuCaps->version >= 1003000)
virQEMUCapsSet(qemuCaps, QEMU_CAPS_MACHINE_USB_OPT);
+ /* WebSockets were introduced between 1.3.0 and 1.3.1 */
+ if (qemuCaps->version >= 1003001)
+ virQEMUCapsSet(qemuCaps, QEMU_CAPS_VNC_WEBSOCKET);
+
if (virQEMUCapsProbeQMPCommands(qemuCaps, mon) < 0)
goto cleanup;
if (virQEMUCapsProbeQMPEvents(qemuCaps, mon) < 0)
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index a9eea4e..4b07b75 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -184,6 +184,7 @@ enum virQEMUCapsFlags {
QEMU_CAPS_VFIO_PCI_BOOTINDEX = 143, /* bootindex param for vfio-pci device */
QEMU_CAPS_DEVICE_SCSI_GENERIC = 144, /* -device scsi-generic */
QEMU_CAPS_DEVICE_SCSI_GENERIC_BOOTINDEX = 145, /* -device scsi-generic.bootindex
*/
+ QEMU_CAPS_VNC_WEBSOCKET = 146, /* -vnc x:y,websocket */
QEMU_CAPS_LAST, /* this must always be the last item */
};
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index eddc263..7d80e74 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -6070,6 +6070,17 @@ qemuBuildGraphicsVNCCommandLine(virQEMUDriverConfigPtr cfg,
}
}
+ if (graphics->data.vnc.websocket) {
+ if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VNC_WEBSOCKET)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("VNC WebSockets are not supported "
+ "with this QEMU binary"));
+ goto error;
+ }
+
+ virBufferAsprintf(&opt, ",websocket=%d",
graphics->data.vnc.websocket);
+ }
+
I think the above block should be moved in
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VNC_COLON)) {
if (graphics->data.vnc.websocket)
...
}
@@ -9915,6 +9928,49 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr qemuCaps,
virDomainGraphicsDefFree(vnc);
goto no_memory;
}
+
+ if (*opts == ',') {
+ char *orig_opts = strdup(opts + 1);
+ if (!orig_opts) {
+ virDomainGraphicsDefFree(vnc);
+ goto no_memory;
+ }
+ opts = orig_opts;
+
+ while (opts && *opts) {
+ char *nextopt = strchr(opts, ',');
+ if (nextopt)
+ *(nextopt++) = '\0';
+
+ if (STRPREFIX(opts, "websocket")) {
+ char *websocket = opts + strlen("websocket");
+ if (*(websocket++) == '=' &&
+ *websocket) {
+ /* If the websocket continues with
+ * '=<something>', we'll parse it */
+ if (virStrToLong_i(websocket,
+ NULL, 0,
+ &vnc->data.vnc.websocket) <
0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("cannot parse VNC "
+ "WebSocket port
'%s'"),
+ websocket);
+ virDomainGraphicsDefFree(vnc);
+ VIR_FREE(orig_opts);
missing goto error, but still nice parsing
The rest is good for me. I use noVNC to connect it, it
works well.
Right now, the 'autoport' attribute only manages automatic
port allocation for 'port'.
'websocket' doesn't use it, -1 means auto port allocation
itself.
If we should change doc to avoid confusing.
ACK with above fixed.
Guannan