On Wed, Jun 27, 2012 at 03:21:48PM +0200, Michal Privoznik wrote: > On 24.06.2012 23:14, Doug Goldstein wrote: > > v2: > > - Refactored to use virBuffer > > - Refactored to use virXPath wrappers > > - Added support for tls-port and password for SPICE > > - Added optional flag to disable SPICE password to the URI > > - Added support for RDP > > - Fixed code reviews > > > > Add a new 'domdisplay' command that provides a URI for VNC, SPICE and > > RDP connections. Presently the 'vncdisplay' command provides you with > > the port info that QEMU is listening on but there is no counterpart for > > SPICE and RDP. Additionally this provides you with the bind address as > > specified in the XML, which the existing 'vncdisplay' lacks. For SPICE > > connections it supports secure and unsecure channels and optionally > > providing the password for the SPICE channel. > > > > Signed-off-by: Doug Goldstein <cardoe@xxxxxxxxxx> > > --- > > tools/virsh.c | 173 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ > > tools/virsh.pod | 6 ++ > > 2 files changed, 179 insertions(+), 0 deletions(-) > > > > diff --git a/tools/virsh.c b/tools/virsh.c > > index 0354822..da80477 100644 > > --- a/tools/virsh.c > > +++ b/tools/virsh.c > > @@ -13827,6 +13827,178 @@ cmdSysinfo (vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) > > } > > > > /* > > + * "display" command > > + */ > > In fact it's domdisplay command. > > > +static const vshCmdInfo info_domdisplay[] = { > > + {"help", N_("domain display connection URI")}, > > + {"desc", N_("Output the IP address and port number for the graphical display.")}, > > + {NULL, NULL} > > +}; > > + > > +static const vshCmdOptDef opts_domdisplay[] = { > > + {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")}, > > + {"include-password", VSH_OT_BOOL, VSH_OFLAG_NONE, N_("includes the password into the connection URI if available")}, > > + {NULL, 0, 0, NULL} > > +}; > > + > > +static bool > > +cmdDomDisplay(vshControl *ctl, const vshCmd *cmd) > > +{ > > + xmlDocPtr xml = NULL; > > + xmlXPathContextPtr ctxt = NULL; > > + virDomainPtr dom; > > + virBuffer buf = VIR_BUFFER_INITIALIZER; > > + bool ret = false; > > + char *doc; > > + char *xpath; > > + char *listen_addr; > > + int port, tls_port = 0; > > + char *passwd = NULL; > > + const char *scheme[] = { "vnc", "spice", "rdp", NULL }; > > + int iter = 0; > > + int tmp; > > + > > + if (!vshConnectionUsability(ctl, ctl->conn)) > > + return false; > > + > > + if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) > > + return false; > > + > > + if (!virDomainIsActive(dom)) { > > + vshError(ctl, _("Domain is not running")); > > + goto cleanup; > > + } > > + > > + doc = virDomainGetXMLDesc(dom, 0); > > + if (!doc) > > + goto cleanup; > > + > > + xml = virXMLParseStringCtxt(doc, _("(domain_definition)"), &ctxt); > > + VIR_FREE(doc); > > + if (!xml) > > + goto cleanup; > > + > > + /* Attempt to grab our display info */ > > + for (iter = 0; scheme[iter] != NULL; iter++) { > > + /* Create our XPATH lookup for the current display's port */ > > + virAsprintf(&xpath, "string(/domain/devices/graphics[@type='%s']" > > + "/@port)", scheme[iter]); > > + if (!xpath) { > > + virReportOOMError(); > > + goto cleanup; > > + } > > + > > + /* Attempt to get the port number for the current graphics scheme */ > > + tmp = virXPathInt(xpath, ctxt, &port); > > + VIR_FREE(xpath); > > + > > + /* If there is no port number for this type, then jump to the next > > + * scheme > > + */ > > + if (tmp) > > + continue; > > + > > + /* Create our XPATH lookup for the current display's address */ > > + virAsprintf(&xpath, "string(/domain/devices/graphics[@type='%s']" > > + "/@listen)", scheme[iter]); > > + if (!xpath) { > > + virReportOOMError(); > > + goto cleanup; > > + } > > + > > + /* Attempt to get the listening addr if set for the current > > + * graphics scheme > > + */ > > + listen_addr = virXPathString(xpath, ctxt); > > + VIR_FREE(xpath); > > + > > Adding a blank line ^^ > > > + /* Per scheme data mangling */ > > + if (STREQ(scheme[iter], "vnc")) { > > + /* VNC protocol handlers take their port number as 'port' - 5900 */ > > + port -= 5900; > > + } else if (STREQ(scheme[iter], "spice")) { > > + /* Create our XPATH lookup for the SPICE TLS Port */ > > + virAsprintf(&xpath, "string(/domain/devices/graphics[@type='%s']" > > + "/@tlsPort)", scheme[iter]); > > + if (!xpath) { > > + virReportOOMError(); > > + goto cleanup; > > + } > > + > > + /* Attempt to get the TLS port number for SPICE */ > > + tmp = virXPathInt(xpath, ctxt, &tls_port); > > + VIR_FREE(xpath); > > + if (tmp) > > + tls_port = 0; > > + > > + if (vshCommandOptBool(cmd, "daemon")) { > > s/daemon/include-password/ > > > + /* Create our XPATH lookup for the SPICE password */ > > + virAsprintf(&xpath, "string(/domain/devices/graphics" > > + "[@type='%s']/@passwd)", scheme[iter]); > > + if (!xpath) { > > + virReportOOMError(); > > + goto cleanup; > > + } > > + > > + /* Attempt to get the SPICE password */ > > + passwd = virXPathString(xpath, ctxt); > > + VIR_FREE(xpath); > > + } > > + } > > + > > + /* Build up the full URI, starting with the scheme */ > > + virBufferAsprintf(&buf, "%s://", scheme[iter]); > > + > > + /* Then host name or IP */ > > + if (!listen_addr || STREQ((const char *)listen_addr, "0.0.0.0")) > > + virBufferAddLit(&buf, "localhost"); > > + else > > + virBufferAsprintf(&buf, "%s", listen_addr); > > + > > + /* Clean up our memory */ > > + if (listen_addr) > > + VIR_FREE(listen_addr); > > This check is redundant. free(NULL) is safe. > > > + > > + /* Add the port */ > > + if (STREQ(scheme[iter], "spice")) > > + virBufferAsprintf(&buf, "?port=%d", port); > > + else > > + virBufferAsprintf(&buf, ":%d", port); > > + > > + /* TLS Port */ > > + if (tls_port) > > + virBufferAsprintf(&buf, "&tls-port=%d", tls_port); > > + > > + /* Password */ > > + if (passwd) { > > + virBufferAsprintf(&buf, "&password=%s", passwd); > > + VIR_FREE(passwd); > > + } > > + > > + /* Ensure we can print our URI */ > > + if (virBufferError(&buf)) { > > + vshPrint(ctl, "%s", _("Failed to create display URI")); > > + goto cleanup; > > + } > > + > > + /* Print out our full URI */ > > + output = virBufferContentAndReset(&buf); > > + vshPrint(ctl, "%s", output); > > + VIR_FREE(output); > > + > > + /* We got what we came for so return successfully */ > > + ret = true; > > + break; > > + } > > + > > +cleanup: > > + xmlXPathFreeContext(ctxt); > > + xmlFreeDoc(xml); > > + virDomainFree(dom); > > + return ret; > > +} > > + > > +/* > > * "vncdisplay" command > > */ > > static const vshCmdInfo info_vncdisplay[] = { > > @@ -17974,6 +18146,7 @@ static const vshCmdDef domManagementCmds[] = { > > {"detach-disk", cmdDetachDisk, opts_detach_disk, info_detach_disk, 0}, > > {"detach-interface", cmdDetachInterface, opts_detach_interface, > > info_detach_interface, 0}, > > + {"domdisplay", cmdDomDisplay, opts_domdisplay, info_domdisplay, 0}, > > {"domid", cmdDomid, opts_domid, info_domid, 0}, > > {"domif-setlink", cmdDomIfSetLink, opts_domif_setlink, info_domif_setlink, 0}, > > {"domiftune", cmdDomIftune, opts_domiftune, info_domiftune, 0}, > > diff --git a/tools/virsh.pod b/tools/virsh.pod > > index f83a29d..558105f 100644 > > --- a/tools/virsh.pod > > +++ b/tools/virsh.pod > > @@ -820,6 +820,12 @@ I<size> is a scaled integer (see B<NOTES> above) which defaults to KiB > > "B" to get bytes (note that for historical reasons, this differs from > > B<vol-resize> which defaults to bytes without a suffix). > > > > +=item B<domdisplay> I<domain-id> [I<--include-password>] > > + > > +Output a URI which can be used to connect to the graphical display of the > > +domain via VNC, SPICE or RDP. If I<--include-password> is specified, the > > +SPICE channel password will be included in the URI. > > + > > =item B<dominfo> I<domain-id> > > > > Returns basic information about the domain. > > > > Otherwise looking good. ACK. I would pushed this but we are in freeze > phase. On the other hand - v1 was sent before freeze. Combined with fact > that number of patches sent into the list has fallen down I guess we can > push this in. But I'd like to hear a second opinion. it only touches virsh, so the risks are limited. And overall a new command is really low risk too, so ACK, let's push it now. I will probably make the rc2 in 12hours if you could push before fine :-) Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@xxxxxxxxxxxx | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/ -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list