This adds an element
<graphics type='spice' port='5903' tlsPort='5904'
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 | 30 +++++++++++++++++++++
src/conf/domain_conf.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++-
src/conf/domain_conf.h | 8 ++++++
src/qemu/qemu_conf.c | 9 ++++++
4 files changed, 111 insertions(+), 1 deletions(-)
diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng
index f9d6d7e..8aa2079 100644
--- a/docs/schemas/domain.rng
+++ b/docs/schemas/domain.rng
@@ -746,6 +746,36 @@
</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="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 4930c38..ca5dfc3 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -165,7 +165,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",
@@ -267,6 +268,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);
@@ -1692,6 +1699,38 @@ virDomainGraphicsDefParseXML(virConnectPtr conn,
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;
+
+ if (port) {
+ if (virStrToLong_i(port, NULL, 10, &def->data.spice.port) < 0) {
+ virDomainReportError(conn, 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(conn, VIR_ERR_INTERNAL_ERROR,
+ _("cannot parse spice tlsPort %s"),
tlsPort);
+ VIR_FREE(tlsPort);
+ goto error;
+ }
+ VIR_FREE(tlsPort);
+ } else {
+ def->data.spice.tlsPort = 0;
+ }
+
+ def->data.spice.listenAddr = virXMLPropString(node, "listen");
+ def->data.spice.passwd = virXMLPropString(node, "passwd");
+ def->data.spice.keymap = virXMLPropString(node, "keymap");
}
cleanup:
@@ -4100,6 +4139,30 @@ virDomainGraphicsDefFormat(virConnectPtr conn,
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);
+
+ 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 7ea1152..4cb10d3 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -334,6 +334,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,
};
@@ -366,6 +367,13 @@ struct _virDomainGraphicsDef {
char *display;
int fullscreen : 1;
} desktop;
+ struct {
+ int port;
+ int tlsPort;
+ char *listenAddr;
+ char *keymap;
+ char *passwd;
+ } spice;
} data;
};
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index 7ba0ac2..ae171bc 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -2067,6 +2067,12 @@ int qemudBuildCommandLine(virConnectPtr conn,
}
}
+ if (def->ngraphics > 1) {
+ qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+ "%s", _("only one graphics output is currently
supported"));
+ goto error;
+ }
+
if ((def->ngraphics == 1) &&
def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC) {
virBuffer opt = VIR_BUFFER_INITIALIZER;
@@ -2155,6 +2161,9 @@ int qemudBuildCommandLine(virConnectPtr conn,
*/
ADD_ENV_COPY("QEMU_AUDIO_DRV");
ADD_ENV_COPY("SDL_AUDIODRIVER");
+ } else if (def->ngraphics) {
+ qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+ "%s", _("unsupported graphics output
requested"));
}
if (def->nvideos) {
--
1.6.2.5