From c909091b748ecb4ae8ad2dac0c15b5f73f5a2dfd Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Fri, 14 Aug 2009 10:54:14 +0100 Subject: [PATCH] Add a type for SPICE protocol This adds an element This is the bare minimum that should be exposed in the guest config for SPICE. Other parameters are better handled as per host level configuration tunables * docs/schemas/domain.rng: Define the SPICE schema * src/domain_conf.h, src/domain_conf.c: Add parsing and formatting for SPICE graphics config * src/qemu_conf.c: Complain about unsupported graphics types --- docs/formatdomain.html.in | 12 ++++++ docs/schemas/domain.rng | 38 +++++++++++++++++++ src/conf/domain_conf.c | 80 ++++++++++++++++++++++++++++++++++++++- src/conf/domain_conf.h | 9 +++++ src/qemu/qemu_conf.c | 2 +- 5 files changed, 139 insertions(+), 2 deletions(-) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index dcb7af887e..e6a8162f7f 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -1102,6 +1102,18 @@ qemu-kvm -net nic,model=? /dev/null The listen attribute is an IP address for the server to listen on. The passwd attribute provides a VNC password in clear text. The keymap attribute specifies the keymap + to use. + +
"spice"
+
+ Starts a SPICE server. The port attribute specifies the TCP + port number (with -1 as legacy syntax indicating that it should be + auto-allocated), while tlsPort gives an alternative + secure port number. The autoport attribute is the new + preferred syntax for indicating autoallocation of both port numbers. + The listen attribute is an IP address for the server to + listen on. The passwd attribute provides a SPICE password + in clear text. The keymap attribute specifies the keymap to use.
"rdp"
diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng index 16fc444df7..7903000680 100644 --- a/docs/schemas/domain.rng +++ b/docs/schemas/domain.rng @@ -1094,6 +1094,44 @@ + + + spice + + + + + + + + + + + + + + + yes + no + + + + + + + + + + + + + + + + + + + rdp diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 09f415b711..1f3bca8cad 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -268,7 +268,8 @@ VIR_ENUM_IMPL(virDomainGraphics, VIR_DOMAIN_GRAPHICS_TYPE_LAST, "sdl", "vnc", "rdp", - "desktop") + "desktop", + "spice") VIR_ENUM_IMPL(virDomainHostdevMode, VIR_DOMAIN_HOSTDEV_MODE_LAST, "subsystem", @@ -451,6 +452,12 @@ void virDomainGraphicsDefFree(virDomainGraphicsDefPtr def) case VIR_DOMAIN_GRAPHICS_TYPE_DESKTOP: VIR_FREE(def->data.desktop.display); break; + + case VIR_DOMAIN_GRAPHICS_TYPE_SPICE: + VIR_FREE(def->data.spice.listenAddr); + VIR_FREE(def->data.spice.keymap); + VIR_FREE(def->data.spice.passwd); + break; } VIR_FREE(def); @@ -3204,6 +3211,50 @@ virDomainGraphicsDefParseXML(xmlNodePtr node, int flags) { def->data.desktop.fullscreen = 0; def->data.desktop.display = virXMLPropString(node, "display"); + } else if (def->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE) { + char *port = virXMLPropString(node, "port"); + char *tlsPort; + char *autoport; + + if (port) { + if (virStrToLong_i(port, NULL, 10, &def->data.spice.port) < 0) { + virDomainReportError(VIR_ERR_INTERNAL_ERROR, + _("cannot parse spice port %s"), port); + VIR_FREE(port); + goto error; + } + VIR_FREE(port); + } else { + def->data.spice.port = 5900; + } + + tlsPort = virXMLPropString(node, "tlsPort"); + if (tlsPort) { + if (virStrToLong_i(tlsPort, NULL, 10, &def->data.spice.tlsPort) < 0) { + virDomainReportError(VIR_ERR_INTERNAL_ERROR, + _("cannot parse spice tlsPort %s"), tlsPort); + VIR_FREE(tlsPort); + goto error; + } + VIR_FREE(tlsPort); + } else { + def->data.spice.tlsPort = 0; + } + + if ((autoport = virXMLPropString(node, "autoport")) != NULL) { + if (STREQ(autoport, "yes")) { + if (flags & VIR_DOMAIN_XML_INACTIVE) { + def->data.spice.port = 0; + def->data.spice.tlsPort = 0; + } + def->data.spice.autoport = 1; + } + VIR_FREE(autoport); + } + + def->data.spice.listenAddr = virXMLPropString(node, "listen"); + def->data.spice.passwd = virXMLPropString(node, "passwd"); + def->data.spice.keymap = virXMLPropString(node, "keymap"); } cleanup: @@ -6517,6 +6568,33 @@ virDomainGraphicsDefFormat(virBufferPtr buf, break; + case VIR_DOMAIN_GRAPHICS_TYPE_SPICE: + if (def->data.spice.port) + virBufferVSprintf(buf, " port='%d'", + def->data.spice.port); + + if (def->data.spice.tlsPort) + virBufferVSprintf(buf, " tlsPort='%d'", + def->data.spice.tlsPort); + + virBufferVSprintf(buf, " autoport='%s'", + def->data.spice.autoport ? "yes" : "no"); + + if (def->data.spice.listenAddr) + virBufferVSprintf(buf, " listen='%s'", + def->data.spice.listenAddr); + + if (def->data.spice.keymap) + virBufferEscapeString(buf, " keymap='%s'", + def->data.spice.keymap); + + if (def->data.spice.passwd && + (flags & VIR_DOMAIN_XML_SECURE)) + virBufferEscapeString(buf, " passwd='%s'", + def->data.spice.passwd); + + break; + } virBufferAddLit(buf, "/>\n"); diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 834eafeb23..c6699e2e54 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -512,6 +512,7 @@ enum virDomainGraphicsType { VIR_DOMAIN_GRAPHICS_TYPE_VNC, VIR_DOMAIN_GRAPHICS_TYPE_RDP, VIR_DOMAIN_GRAPHICS_TYPE_DESKTOP, + VIR_DOMAIN_GRAPHICS_TYPE_SPICE, VIR_DOMAIN_GRAPHICS_TYPE_LAST, }; @@ -544,6 +545,14 @@ struct _virDomainGraphicsDef { char *display; unsigned int fullscreen :1; } desktop; + struct { + int port; + int tlsPort; + char *listenAddr; + char *keymap; + char *passwd; + unsigned int autoport :1; + } spice; } data; }; diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index e0064f75e1..e8342be48b 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -5072,7 +5072,7 @@ int qemudBuildCommandLine(virConnectPtr conn, if (def->nvideos) { if (def->nvideos > 1) { - qemuReportError(VIR_ERR_INTERNAL_ERROR, + qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("only one video card is currently supported")); goto error; } -- 2.47.2