This adds an element <graphics type='spice' port='5903' tlsPort='5904' autoport='yes' listen='127.0.0.1'/> 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 <graphics> 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/schemas/domain.rng | 38 ++++++++++++++++++++++ src/conf/domain_conf.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++- src/conf/domain_conf.h | 9 +++++ src/qemu/qemu_conf.c | 2 +- 4 files changed, 127 insertions(+), 2 deletions(-) diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng index c8beffc..3163257 100644 --- a/docs/schemas/domain.rng +++ b/docs/schemas/domain.rng @@ -1090,6 +1090,44 @@ </group> <group> <attribute name="type"> + <value>spice</value> + </attribute> + <optional> + <attribute name="port"> + <ref name="PortNumber"/> + </attribute> + </optional> + <optional> + <attribute name="tlsPort"> + <ref name="PortNumber"/> + </attribute> + </optional> + <optional> + <attribute name="autoport"> + <choice> + <value>yes</value> + <value>no</value> + </choice> + </attribute> + </optional> + <optional> + <attribute name="listen"> + <ref name="addrIP"/> + </attribute> + </optional> + <optional> + <attribute name="passwd"> + <text/> + </attribute> + </optional> + <optional> + <attribute name="keymap"> + <text/> + </attribute> + </optional> + </group> + <group> + <attribute name="type"> <value>rdp</value> </attribute> <optional> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 8907563..a3ea217 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -259,7 +259,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", @@ -446,6 +447,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); @@ -3202,6 +3209,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: @@ -6355,6 +6406,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 78f28d0..0238f92 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -511,6 +511,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, }; @@ -543,6 +544,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 149dcee..aa42e04 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -4949,7 +4949,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; } -- 1.7.2.3 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list