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 <mklet...@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

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Reply via email to