virsh: cmdDomDisplay: Extract loop body fetching display URIs into 'virshGetOneDisplay'

Separate the code so that the function is not as massive. Note that this
is a minimal extraction which does not clean up the code meant for
looping.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
Peter Krempa 2022-02-28 16:32:50 +01:00
parent c6bb274693
commit 364b4f0a0d

View File

@ -11659,59 +11659,28 @@ static const vshCmdOptDef opts_domdisplay[] = {
{.name = NULL}
};
static bool
cmdDomDisplay(vshControl *ctl, const vshCmd *cmd)
static char *
virshGetOneDisplay(vshControl *ctl,
const char *scheme,
xmlXPathContext *ctxt)
{
g_autoptr(xmlDoc) xml = NULL;
g_autoptr(xmlXPathContext) ctxt = NULL;
g_autoptr(virshDomain) dom = NULL;
const char *xpath_fmt = "string(/domain/devices/graphics[@type='%s']/%s)";
g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
bool ret = false;
char *xpath = NULL;
char *listen_addr = NULL;
int port, tls_port = 0;
int port = 0;
int tls_port = 0;
char *type_conn = NULL;
char *sockpath = NULL;
char *passwd = NULL;
char *output = NULL;
const char *scheme[] = { "vnc", "spice", "rdp", NULL };
const char *type = NULL;
int iter = 0;
int tmp;
int flags = 0;
bool params = false;
bool all = vshCommandOptBool(cmd, "all");
const char *xpath_fmt = "string(/domain/devices/graphics[@type='%s']/%s)";
virSocketAddr addr;
VSH_EXCLUSIVE_OPTIONS("all", "type");
if (!(dom = virshCommandOptDomain(ctl, cmd, NULL)))
return false;
if (!virDomainIsActive(dom)) {
vshError(ctl, _("Domain is not running"));
goto cleanup;
}
if (vshCommandOptBool(cmd, "include-password"))
flags |= VIR_DOMAIN_XML_SECURE;
if (vshCommandOptStringReq(ctl, cmd, "type", &type) < 0)
goto cleanup;
if (virshDomainGetXMLFromDom(ctl, dom, flags, &xml, &ctxt) < 0)
goto cleanup;
/* Attempt to grab our display info */
for (iter = 0; scheme[iter] != NULL; iter++) {
/* Particular scheme requested */
if (!all && type && STRNEQ(type, scheme[iter]))
continue;
/* Create our XPATH lookup for the current display's port */
VIR_FREE(xpath);
xpath = g_strdup_printf(xpath_fmt, scheme[iter], "@port");
xpath = g_strdup_printf(xpath_fmt, scheme, "@port");
/* Attempt to get the port number for the current graphics scheme */
tmp = virXPathInt(xpath, ctxt, &port);
@ -11724,7 +11693,7 @@ cmdDomDisplay(vshControl *ctl, const vshCmd *cmd)
/* Create our XPATH lookup for TLS Port (automatically skipped
* for unsupported schemes */
xpath = g_strdup_printf(xpath_fmt, scheme[iter], "@tlsPort");
xpath = g_strdup_printf(xpath_fmt, scheme, "@tlsPort");
/* Attempt to get the TLS port number */
tmp = virXPathInt(xpath, ctxt, &tls_port);
@ -11733,7 +11702,7 @@ cmdDomDisplay(vshControl *ctl, const vshCmd *cmd)
tls_port = 0;
/* Create our XPATH lookup for the current display's address */
xpath = g_strdup_printf(xpath_fmt, scheme[iter], "@listen");
xpath = g_strdup_printf(xpath_fmt, scheme, "@listen");
/* Attempt to get the listening addr if set for the current
* graphics scheme */
@ -11742,7 +11711,7 @@ cmdDomDisplay(vshControl *ctl, const vshCmd *cmd)
VIR_FREE(xpath);
/* Create our XPATH lookup for the current spice type. */
xpath = g_strdup_printf(xpath_fmt, scheme[iter], "listen/@type");
xpath = g_strdup_printf(xpath_fmt, scheme, "listen/@type");
/* Attempt to get the type of spice connection */
VIR_FREE(type_conn);
@ -11751,7 +11720,7 @@ cmdDomDisplay(vshControl *ctl, const vshCmd *cmd)
if (STREQ_NULLABLE(type_conn, "socket")) {
if (!sockpath) {
xpath = g_strdup_printf(xpath_fmt, scheme[iter], "listen/@socket");
xpath = g_strdup_printf(xpath_fmt, scheme, "listen/@socket");
sockpath = virXPathString(xpath, ctxt);
@ -11760,7 +11729,7 @@ cmdDomDisplay(vshControl *ctl, const vshCmd *cmd)
}
if (!port && !tls_port && !sockpath)
continue;
goto cleanup;
if (!listen_addr) {
/* The subelement address - <listen address='xyz'/> -
@ -11771,7 +11740,7 @@ cmdDomDisplay(vshControl *ctl, const vshCmd *cmd)
* subelement (which, by the way, doesn't exist on libvirt
* < 0.9.4, so we really do need to check both places)
*/
xpath = g_strdup_printf(xpath_fmt, scheme[iter], "listen/@address");
xpath = g_strdup_printf(xpath_fmt, scheme, "listen/@address");
listen_addr = virXPathString(xpath, ctxt);
VIR_FREE(xpath);
@ -11807,7 +11776,7 @@ cmdDomDisplay(vshControl *ctl, const vshCmd *cmd)
* care of when getting the XML */
/* Create our XPATH lookup for the password */
xpath = g_strdup_printf(xpath_fmt, scheme[iter], "@passwd");
xpath = g_strdup_printf(xpath_fmt, scheme, "@passwd");
/* Attempt to get the password */
VIR_FREE(passwd);
@ -11816,12 +11785,12 @@ cmdDomDisplay(vshControl *ctl, const vshCmd *cmd)
/* Build up the full URI, starting with the scheme */
if (sockpath)
virBufferAsprintf(&buf, "%s+unix://", scheme[iter]);
virBufferAsprintf(&buf, "%s+unix://", scheme);
else
virBufferAsprintf(&buf, "%s://", scheme[iter]);
virBufferAsprintf(&buf, "%s://", scheme);
/* There is no user, so just append password if there's any */
if (STREQ(scheme[iter], "vnc") && passwd)
if (STREQ(scheme, "vnc") && passwd)
virBufferAsprintf(&buf, ":%s@", passwd);
/* Then host name or IP */
@ -11839,7 +11808,7 @@ cmdDomDisplay(vshControl *ctl, const vshCmd *cmd)
/* Add the port */
if (port) {
if (STREQ(scheme[iter], "vnc")) {
if (STREQ(scheme, "vnc")) {
/* VNC protocol handlers take their port number as
* 'port' - 5900 */
port -= 5900;
@ -11856,7 +11825,7 @@ cmdDomDisplay(vshControl *ctl, const vshCmd *cmd)
params = true;
}
if (STREQ(scheme[iter], "spice") && passwd) {
if (STREQ(scheme, "spice") && passwd) {
virBufferAsprintf(&buf,
"%spassword=%s",
params ? "&" : "?",
@ -11864,10 +11833,61 @@ cmdDomDisplay(vshControl *ctl, const vshCmd *cmd)
params = true;
}
/* Print out our full URI */
VIR_FREE(output);
output = virBufferContentAndReset(&buf);
vshPrint(ctl, "%s", output);
cleanup:
VIR_FREE(xpath);
VIR_FREE(type_conn);
VIR_FREE(sockpath);
VIR_FREE(passwd);
VIR_FREE(listen_addr);
return virBufferContentAndReset(&buf);
}
static bool
cmdDomDisplay(vshControl *ctl, const vshCmd *cmd)
{
g_autoptr(xmlDoc) xml = NULL;
g_autoptr(xmlXPathContext) ctxt = NULL;
g_autoptr(virshDomain) dom = NULL;
bool ret = false;
const char *scheme[] = { "vnc", "spice", "rdp", NULL };
const char *type = NULL;
int iter = 0;
int flags = 0;
bool all = vshCommandOptBool(cmd, "all");
VSH_EXCLUSIVE_OPTIONS("all", "type");
if (!(dom = virshCommandOptDomain(ctl, cmd, NULL)))
return false;
if (!virDomainIsActive(dom)) {
vshError(ctl, _("Domain is not running"));
goto cleanup;
}
if (vshCommandOptBool(cmd, "include-password"))
flags |= VIR_DOMAIN_XML_SECURE;
if (vshCommandOptStringReq(ctl, cmd, "type", &type) < 0)
goto cleanup;
if (virshDomainGetXMLFromDom(ctl, dom, flags, &xml, &ctxt) < 0)
goto cleanup;
/* Attempt to grab our display info */
for (iter = 0; scheme[iter] != NULL; iter++) {
g_autofree char *display = NULL;
/* Particular scheme requested */
if (!all && type && STRNEQ(type, scheme[iter]))
continue;
if (!(display = virshGetOneDisplay(ctl, scheme[iter], ctxt)))
continue;
vshPrint(ctl, "%s", display);
/* We got what we came for so return successfully */
ret = true;
@ -11884,12 +11904,6 @@ cmdDomDisplay(vshControl *ctl, const vshCmd *cmd)
}
cleanup:
VIR_FREE(xpath);
VIR_FREE(type_conn);
VIR_FREE(sockpath);
VIR_FREE(passwd);
VIR_FREE(listen_addr);
VIR_FREE(output);
return ret;
}