mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-18 10:35:20 +00:00
virsh: add support for network port APIs
Reviewed-by: Laine Stump <laine@laine.org> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
parent
0e2ef3a954
commit
c2dd9ddf7b
@ -408,6 +408,56 @@ virshNetworkEventNameCompleter(vshControl *ctl ATTRIBUTE_UNUSED,
|
||||
}
|
||||
|
||||
|
||||
char **
|
||||
virshNetworkPortUUIDCompleter(vshControl *ctl,
|
||||
const vshCmd *cmd ATTRIBUTE_UNUSED,
|
||||
unsigned int flags)
|
||||
{
|
||||
virshControlPtr priv = ctl->privData;
|
||||
virNetworkPtr net = NULL;
|
||||
virNetworkPortPtr *ports = NULL;
|
||||
int nports = 0;
|
||||
size_t i = 0;
|
||||
char **ret = NULL;
|
||||
|
||||
virCheckFlags(0, NULL);
|
||||
|
||||
if (!priv->conn || virConnectIsAlive(priv->conn) <= 0)
|
||||
return NULL;
|
||||
|
||||
if (!(net = virshCommandOptNetwork(ctl, cmd, NULL)))
|
||||
return false;
|
||||
|
||||
if ((nports = virNetworkListAllPorts(net, &ports, flags)) < 0)
|
||||
return NULL;
|
||||
|
||||
if (VIR_ALLOC_N(ret, nports + 1) < 0)
|
||||
goto error;
|
||||
|
||||
for (i = 0; i < nports; i++) {
|
||||
char uuid[VIR_UUID_STRING_BUFLEN];
|
||||
|
||||
if (virNetworkPortGetUUIDString(ports[i], uuid) < 0 ||
|
||||
VIR_STRDUP(ret[i], uuid) < 0)
|
||||
goto error;
|
||||
|
||||
virNetworkPortFree(ports[i]);
|
||||
}
|
||||
VIR_FREE(ports);
|
||||
|
||||
return ret;
|
||||
|
||||
error:
|
||||
for (; i < nports; i++)
|
||||
virNetworkPortFree(ports[i]);
|
||||
VIR_FREE(ports);
|
||||
for (i = 0; i < nports; i++)
|
||||
VIR_FREE(ret[i]);
|
||||
VIR_FREE(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
char **
|
||||
virshNodeDeviceNameCompleter(vshControl *ctl,
|
||||
const vshCmd *cmd ATTRIBUTE_UNUSED,
|
||||
|
@ -59,6 +59,10 @@ char ** virshNetworkEventNameCompleter(vshControl *ctl,
|
||||
const vshCmd *cmd,
|
||||
unsigned int flags);
|
||||
|
||||
char ** virshNetworkPortUUIDCompleter(vshControl *ctl,
|
||||
const vshCmd *cmd,
|
||||
unsigned int flags);
|
||||
|
||||
char ** virshNodeDeviceNameCompleter(vshControl *ctl,
|
||||
const vshCmd *cmd,
|
||||
unsigned int flags);
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* virsh-network.c: Commands to manage network
|
||||
*
|
||||
* Copyright (C) 2005, 2007-2016 Red Hat, Inc.
|
||||
* Copyright (C) 2005, 2007-2019 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@ -54,6 +54,16 @@
|
||||
#define VIRSH_COMMON_OPT_NETWORK_OT_STRING_FULL(cflags) \
|
||||
VIRSH_COMMON_OPT_NETWORK_OT_STRING(N_("network name or uuid"), cflags)
|
||||
|
||||
#define VIRSH_COMMON_OPT_NETWORK_PORT(cflags) \
|
||||
{.name = "port", \
|
||||
.type = VSH_OT_DATA, \
|
||||
.flags = VSH_OFLAG_REQ, \
|
||||
.help = N_("port UUID"), \
|
||||
.completer = virshNetworkPortUUIDCompleter, \
|
||||
.completer_flags = cflags, \
|
||||
}
|
||||
|
||||
|
||||
virNetworkPtr
|
||||
virshCommandOptNetworkBy(vshControl *ctl, const vshCmd *cmd,
|
||||
const char **name, unsigned int flags)
|
||||
@ -92,6 +102,35 @@ virshCommandOptNetworkBy(vshControl *ctl, const vshCmd *cmd,
|
||||
return network;
|
||||
}
|
||||
|
||||
|
||||
virNetworkPortPtr
|
||||
virshCommandOptNetworkPort(vshControl *ctl, const vshCmd *cmd,
|
||||
virNetworkPtr net,
|
||||
const char **name)
|
||||
{
|
||||
virNetworkPortPtr port = NULL;
|
||||
const char *n = NULL;
|
||||
const char *optname = "port";
|
||||
|
||||
if (vshCommandOptStringReq(ctl, cmd, optname, &n) < 0)
|
||||
return NULL;
|
||||
|
||||
vshDebug(ctl, VSH_ERR_INFO, "%s: found option <%s>: %s\n",
|
||||
cmd->def->name, optname, n);
|
||||
|
||||
if (name)
|
||||
*name = n;
|
||||
|
||||
vshDebug(ctl, VSH_ERR_DEBUG, "%s: <%s> trying as network UUID\n",
|
||||
cmd->def->name, optname);
|
||||
port = virNetworkPortLookupByUUIDString(net, n);
|
||||
|
||||
if (!port)
|
||||
vshError(ctl, _("failed to get network port '%s'"), n);
|
||||
|
||||
return port;
|
||||
}
|
||||
|
||||
/*
|
||||
* "net-autostart" command
|
||||
*/
|
||||
@ -1437,6 +1476,340 @@ cmdNetworkDHCPLeases(vshControl *ctl, const vshCmd *cmd)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* "net-port-create" command
|
||||
*/
|
||||
static const vshCmdInfo info_network_port_create[] = {
|
||||
{.name = "help",
|
||||
.data = N_("create a network port from an XML file")
|
||||
},
|
||||
{.name = "desc",
|
||||
.data = N_("Create a network port.")
|
||||
},
|
||||
{.name = NULL}
|
||||
};
|
||||
|
||||
static const vshCmdOptDef opts_network_port_create[] = {
|
||||
VIRSH_COMMON_OPT_NETWORK_FULL(0),
|
||||
VIRSH_COMMON_OPT_FILE(N_("file containing an XML network port description")),
|
||||
{.name = NULL}
|
||||
};
|
||||
|
||||
static bool
|
||||
cmdNetworkPortCreate(vshControl *ctl, const vshCmd *cmd)
|
||||
{
|
||||
virNetworkPortPtr port = NULL;
|
||||
const char *from = NULL;
|
||||
bool ret = false;
|
||||
char *buffer = NULL;
|
||||
virNetworkPtr network = NULL;
|
||||
|
||||
network = virshCommandOptNetwork(ctl, cmd, NULL);
|
||||
if (network == NULL)
|
||||
goto cleanup;
|
||||
|
||||
if (vshCommandOptStringReq(ctl, cmd, "file", &from) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (virFileReadAll(from, VSH_MAX_XML_FILE, &buffer) < 0)
|
||||
goto cleanup;
|
||||
|
||||
port = virNetworkPortCreateXML(network, buffer, 0);
|
||||
|
||||
if (port != NULL) {
|
||||
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
||||
virNetworkPortGetUUIDString(port, uuidstr);
|
||||
vshPrintExtra(ctl, _("Network port %s created from %s\n"),
|
||||
uuidstr, from);
|
||||
} else {
|
||||
vshError(ctl, _("Failed to create network from %s"), from);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ret = true;
|
||||
cleanup:
|
||||
VIR_FREE(buffer);
|
||||
if (port)
|
||||
virNetworkPortFree(port);
|
||||
if (network)
|
||||
virNetworkFree(network);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* "net-port-dumpxml" command
|
||||
*/
|
||||
static const vshCmdInfo info_network_port_dumpxml[] = {
|
||||
{.name = "help",
|
||||
.data = N_("network port information in XML")
|
||||
},
|
||||
{.name = "desc",
|
||||
.data = N_("Output the network port information as an XML dump to stdout.")
|
||||
},
|
||||
{.name = NULL}
|
||||
};
|
||||
|
||||
static const vshCmdOptDef opts_network_port_dumpxml[] = {
|
||||
VIRSH_COMMON_OPT_NETWORK_FULL(0),
|
||||
VIRSH_COMMON_OPT_NETWORK_PORT(0),
|
||||
{.name = NULL}
|
||||
};
|
||||
|
||||
static bool
|
||||
cmdNetworkPortDumpXML(vshControl *ctl, const vshCmd *cmd)
|
||||
{
|
||||
virNetworkPtr network;
|
||||
virNetworkPortPtr port = NULL;
|
||||
bool ret = true;
|
||||
char *dump;
|
||||
unsigned int flags = 0;
|
||||
|
||||
if (!(network = virshCommandOptNetwork(ctl, cmd, NULL)))
|
||||
goto cleanup;
|
||||
|
||||
if (!(port = virshCommandOptNetworkPort(ctl, cmd, network, NULL)))
|
||||
goto cleanup;
|
||||
|
||||
dump = virNetworkPortGetXMLDesc(port, flags);
|
||||
|
||||
if (dump != NULL) {
|
||||
vshPrint(ctl, "%s", dump);
|
||||
VIR_FREE(dump);
|
||||
} else {
|
||||
ret = false;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (port)
|
||||
virNetworkPortFree(port);
|
||||
if (network)
|
||||
virNetworkFree(network);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* "net-port-delete" command
|
||||
*/
|
||||
static const vshCmdInfo info_network_port_delete[] = {
|
||||
{.name = "help",
|
||||
.data = N_("network port information in XML")
|
||||
},
|
||||
{.name = "desc",
|
||||
.data = N_("Output the network port information as an XML dump to stdout.")
|
||||
},
|
||||
{.name = NULL}
|
||||
};
|
||||
|
||||
static const vshCmdOptDef opts_network_port_delete[] = {
|
||||
VIRSH_COMMON_OPT_NETWORK_FULL(0),
|
||||
VIRSH_COMMON_OPT_NETWORK_PORT(0),
|
||||
{.name = NULL}
|
||||
};
|
||||
|
||||
static bool
|
||||
cmdNetworkPortDelete(vshControl *ctl, const vshCmd *cmd)
|
||||
{
|
||||
virNetworkPtr network = NULL;
|
||||
virNetworkPortPtr port = NULL;
|
||||
bool ret = true;
|
||||
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
||||
|
||||
if (!(network = virshCommandOptNetwork(ctl, cmd, NULL)))
|
||||
goto cleanup;
|
||||
|
||||
if (!(port = virshCommandOptNetworkPort(ctl, cmd, network, NULL)))
|
||||
goto cleanup;
|
||||
|
||||
if (virNetworkPortGetUUIDString(port, uuidstr) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (virNetworkPortDelete(port, 0) < 0) {
|
||||
vshError(ctl, _("Failed to delete network port %s"), uuidstr);
|
||||
goto cleanup;
|
||||
} else {
|
||||
vshPrintExtra(ctl, _("Network port %s deleted\n"), uuidstr);
|
||||
}
|
||||
|
||||
ret = true;
|
||||
cleanup:
|
||||
if (port)
|
||||
virNetworkPortFree(port);
|
||||
if (network)
|
||||
virNetworkFree(network);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
virshNetworkPortSorter(const void *a, const void *b)
|
||||
{
|
||||
virNetworkPortPtr *na = (virNetworkPortPtr *) a;
|
||||
virNetworkPortPtr *nb = (virNetworkPortPtr *) b;
|
||||
unsigned char uuida[VIR_UUID_BUFLEN];
|
||||
unsigned char uuidb[VIR_UUID_BUFLEN];
|
||||
|
||||
if (*na && !*nb)
|
||||
return -1;
|
||||
|
||||
if (!*na)
|
||||
return *nb != NULL;
|
||||
|
||||
if (virNetworkPortGetUUID(*na, uuida) < 0 ||
|
||||
virNetworkPortGetUUID(*nb, uuidb) < 0)
|
||||
return -1;
|
||||
|
||||
return memcmp(uuida, uuidb, VIR_UUID_BUFLEN);
|
||||
}
|
||||
|
||||
struct virshNetworkPortList {
|
||||
virNetworkPortPtr *ports;
|
||||
size_t nports;
|
||||
};
|
||||
typedef struct virshNetworkPortList *virshNetworkPortListPtr;
|
||||
|
||||
static void
|
||||
virshNetworkPortListFree(virshNetworkPortListPtr list)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (list && list->ports) {
|
||||
for (i = 0; i < list->nports; i++) {
|
||||
if (list->ports[i])
|
||||
virNetworkPortFree(list->ports[i]);
|
||||
}
|
||||
VIR_FREE(list->ports);
|
||||
}
|
||||
VIR_FREE(list);
|
||||
}
|
||||
|
||||
static virshNetworkPortListPtr
|
||||
virshNetworkPortListCollect(vshControl *ctl,
|
||||
const vshCmd *cmd,
|
||||
unsigned int flags)
|
||||
{
|
||||
virshNetworkPortListPtr list = vshMalloc(ctl, sizeof(*list));
|
||||
int ret;
|
||||
virNetworkPtr network = NULL;
|
||||
bool success = false;
|
||||
|
||||
if (!(network = virshCommandOptNetwork(ctl, cmd, NULL)))
|
||||
goto cleanup;
|
||||
|
||||
/* try the list with flags support (0.10.2 and later) */
|
||||
if ((ret = virNetworkListAllPorts(network,
|
||||
&list->ports,
|
||||
flags)) < 0)
|
||||
goto cleanup;
|
||||
|
||||
list->nports = ret;
|
||||
|
||||
/* sort the list */
|
||||
if (list->ports && list->nports)
|
||||
qsort(list->ports, list->nports,
|
||||
sizeof(*list->ports), virshNetworkPortSorter);
|
||||
|
||||
success = true;
|
||||
|
||||
cleanup:
|
||||
if (!success) {
|
||||
virshNetworkPortListFree(list);
|
||||
list = NULL;
|
||||
}
|
||||
|
||||
if (network)
|
||||
virNetworkFree(network);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/*
|
||||
* "net-list" command
|
||||
*/
|
||||
static const vshCmdInfo info_network_port_list[] = {
|
||||
{.name = "help",
|
||||
.data = N_("list network ports")
|
||||
},
|
||||
{.name = "desc",
|
||||
.data = N_("Returns list of network ports.")
|
||||
},
|
||||
{.name = NULL}
|
||||
};
|
||||
|
||||
static const vshCmdOptDef opts_network_port_list[] = {
|
||||
VIRSH_COMMON_OPT_NETWORK_FULL(0),
|
||||
{.name = "uuid",
|
||||
.type = VSH_OT_BOOL,
|
||||
.help = N_("list uuid's only")
|
||||
},
|
||||
{.name = "table",
|
||||
.type = VSH_OT_BOOL,
|
||||
.help = N_("list table (default)")
|
||||
},
|
||||
{.name = NULL}
|
||||
};
|
||||
|
||||
#define FILTER(NAME, FLAG) \
|
||||
if (vshCommandOptBool(cmd, NAME)) \
|
||||
flags |= (FLAG)
|
||||
static bool
|
||||
cmdNetworkPortList(vshControl *ctl, const vshCmd *cmd)
|
||||
{
|
||||
virshNetworkPortListPtr list = NULL;
|
||||
size_t i;
|
||||
bool ret = false;
|
||||
bool optTable = vshCommandOptBool(cmd, "table");
|
||||
bool optUUID = vshCommandOptBool(cmd, "uuid");
|
||||
char uuid[VIR_UUID_STRING_BUFLEN];
|
||||
unsigned int flags = 0;
|
||||
vshTablePtr table = NULL;
|
||||
|
||||
if (optTable + optUUID > 1) {
|
||||
vshError(ctl, "%s",
|
||||
_("Only one argument from --table and --uuid "
|
||||
"may be specified."));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!optUUID)
|
||||
optTable = true;
|
||||
|
||||
if (!(list = virshNetworkPortListCollect(ctl, cmd, flags)))
|
||||
return false;
|
||||
|
||||
if (optTable) {
|
||||
table = vshTableNew(_("UUID"), NULL);
|
||||
if (!table)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
for (i = 0; i < list->nports; i++) {
|
||||
virNetworkPortPtr port = list->ports[i];
|
||||
|
||||
if (virNetworkPortGetUUIDString(port, uuid) < 0) {
|
||||
vshError(ctl, "%s", _("Failed to get network's UUID"));
|
||||
goto cleanup;
|
||||
}
|
||||
if (optTable) {
|
||||
if (vshTableRowAppend(table, uuid, NULL) < 0)
|
||||
goto cleanup;
|
||||
} else if (optUUID) {
|
||||
vshPrint(ctl, "%s\n", uuid);
|
||||
}
|
||||
}
|
||||
|
||||
if (optTable)
|
||||
vshTablePrintToStdout(table, ctl);
|
||||
|
||||
ret = true;
|
||||
cleanup:
|
||||
vshTableFree(table);
|
||||
virshNetworkPortListFree(list);
|
||||
return ret;
|
||||
}
|
||||
#undef FILTER
|
||||
|
||||
|
||||
const vshCmdDef networkCmds[] = {
|
||||
{.name = "net-autostart",
|
||||
.handler = cmdNetworkAutostart,
|
||||
@ -1528,5 +1901,29 @@ const vshCmdDef networkCmds[] = {
|
||||
.info = info_network_uuid,
|
||||
.flags = 0
|
||||
},
|
||||
{.name = "net-port-list",
|
||||
.handler = cmdNetworkPortList,
|
||||
.opts = opts_network_port_list,
|
||||
.info = info_network_port_list,
|
||||
.flags = 0
|
||||
},
|
||||
{.name = "net-port-create",
|
||||
.handler = cmdNetworkPortCreate,
|
||||
.opts = opts_network_port_create,
|
||||
.info = info_network_port_create,
|
||||
.flags = 0
|
||||
},
|
||||
{.name = "net-port-dumpxml",
|
||||
.handler = cmdNetworkPortDumpXML,
|
||||
.opts = opts_network_port_dumpxml,
|
||||
.info = info_network_port_dumpxml,
|
||||
.flags = 0
|
||||
},
|
||||
{.name = "net-port-delete",
|
||||
.handler = cmdNetworkPortDelete,
|
||||
.opts = opts_network_port_delete,
|
||||
.info = info_network_port_delete,
|
||||
.flags = 0
|
||||
},
|
||||
{.name = NULL}
|
||||
};
|
||||
|
@ -27,6 +27,11 @@ virNetworkPtr
|
||||
virshCommandOptNetworkBy(vshControl *ctl, const vshCmd *cmd,
|
||||
const char **name, unsigned int flags);
|
||||
|
||||
virNetworkPortPtr
|
||||
virshCommandOptNetworkPort(vshControl *ctl, const vshCmd *cmd,
|
||||
virNetworkPtr net,
|
||||
const char **name);
|
||||
|
||||
/* default is lookup by Name and UUID */
|
||||
# define virshCommandOptNetwork(_ctl, _cmd, _name) \
|
||||
virshCommandOptNetworkBy(_ctl, _cmd, _name, \
|
||||
|
Loading…
x
Reference in New Issue
Block a user