New virsh feature: domif-setlink --domain --interface --state completer

After you go through command mentioned above, completer
finds what state the device is currently in, and suggests
an opposite state.

Signed-off-by: Simon Kobyda <skobyda@redhat.com>
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
Simon Kobyda 2018-07-12 16:07:59 +02:00 committed by Michal Privoznik
parent 9413442224
commit 728ad0e82b
3 changed files with 78 additions and 0 deletions

View File

@ -32,6 +32,7 @@
#include "internal.h" #include "internal.h"
#include "virutil.h" #include "virutil.h"
#include "viralloc.h" #include "viralloc.h"
#include "virmacaddr.h"
#include "virstring.h" #include "virstring.h"
#include "virxml.h" #include "virxml.h"
@ -777,6 +778,78 @@ virshPoolEventNameCompleter(vshControl *ctl ATTRIBUTE_UNUSED,
} }
char **
virshDomainInterfaceStateCompleter(vshControl *ctl,
const vshCmd *cmd,
unsigned int flags)
{
virshControlPtr priv = ctl->privData;
const char *iface = NULL;
char **ret = NULL;
xmlDocPtr xml = NULL;
xmlXPathContextPtr ctxt = NULL;
virMacAddr macaddr;
char macstr[VIR_MAC_STRING_BUFLEN] = "";
int ninterfaces;
xmlNodePtr *interfaces = NULL;
char *xpath = NULL;
char *state = NULL;
virCheckFlags(0, NULL);
if (!priv->conn || virConnectIsAlive(priv->conn) <= 0)
return NULL;
if (virshDomainGetXML(ctl, cmd, flags, &xml, &ctxt) < 0)
goto cleanup;
if (vshCommandOptStringReq(ctl, cmd, "interface", &iface) < 0)
goto cleanup;
/* normalize the mac addr */
if (virMacAddrParse(iface, &macaddr) == 0)
virMacAddrFormat(&macaddr, macstr);
if (virAsprintf(&xpath, "/domain/devices/interface[(mac/@address = '%s') or "
" (target/@dev = '%s')]",
macstr, iface) < 0)
goto cleanup;
if ((ninterfaces = virXPathNodeSet(xpath, ctxt, &interfaces)) < 0)
goto cleanup;
if (ninterfaces != 1)
goto cleanup;
ctxt->node = interfaces[0];
if (VIR_ALLOC_N(ret, 2) < 0)
goto error;
if ((state = virXPathString("string(./link/@state)", ctxt)) &&
STREQ(state, "down")) {
if (VIR_STRDUP(ret[0], "up") < 0)
goto error;
} else {
if (VIR_STRDUP(ret[0], "down") < 0)
goto error;
}
cleanup:
VIR_FREE(state);
VIR_FREE(xpath);
VIR_FREE(interfaces);
xmlXPathFreeContext(ctxt);
xmlFreeDoc(xml);
return ret;
error:
virStringListFree(ret);
ret = NULL;
goto cleanup;
}
char ** char **
virshNodedevEventNameCompleter(vshControl *ctl ATTRIBUTE_UNUSED, virshNodedevEventNameCompleter(vshControl *ctl ATTRIBUTE_UNUSED,
const vshCmd *cmd ATTRIBUTE_UNUSED, const vshCmd *cmd ATTRIBUTE_UNUSED,

View File

@ -94,6 +94,10 @@ char ** virshPoolEventNameCompleter(vshControl *ctl,
const vshCmd *cmd, const vshCmd *cmd,
unsigned int flags); unsigned int flags);
char ** virshDomainInterfaceStateCompleter(vshControl *ctl,
const vshCmd *cmd,
unsigned int flags);
char ** virshNodedevEventNameCompleter(vshControl *ctl, char ** virshNodedevEventNameCompleter(vshControl *ctl,
const vshCmd *cmd, const vshCmd *cmd,
unsigned int flags); unsigned int flags);

View File

@ -3064,6 +3064,7 @@ static const vshCmdOptDef opts_domif_setlink[] = {
{.name = "state", {.name = "state",
.type = VSH_OT_DATA, .type = VSH_OT_DATA,
.flags = VSH_OFLAG_REQ, .flags = VSH_OFLAG_REQ,
.completer = virshDomainInterfaceStateCompleter,
.help = N_("new state of the device") .help = N_("new state of the device")
}, },
{.name = "persistent", {.name = "persistent",