Adding Public Get and Set APIs for Network Metadata

This patch introduces public Get and Set APIs for modifying <title>,
<description> and <metadata> elements of the Network object.

- Added enum virNetworkMetadataType to select one of the above
  elements to operate on.
- Added error code and messages for missing metadata.
- Added public API implementation.
- Added driver support.

Signed-off-by: K Shiva Kiran <shiva_kr@riseup.net>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
K Shiva Kiran 2023-08-17 00:17:10 +05:30 committed by Michal Privoznik
parent 742c87d453
commit 5b6d41ccb0
6 changed files with 222 additions and 0 deletions

View File

@ -547,4 +547,33 @@ virNetworkPortFree(virNetworkPortPtr port);
int
virNetworkPortRef(virNetworkPortPtr port);
/**
* virNetworkMetadataType:
*
* Since: 9.7.0
*/
typedef enum {
VIR_NETWORK_METADATA_DESCRIPTION = 0, /* Operate on <description> (Since: 9.7.0) */
VIR_NETWORK_METADATA_TITLE = 1, /* Operate on <title> (Since: 9.7.0) */
VIR_NETWORK_METADATA_ELEMENT = 2, /* Operate on <metadata> (Since: 9.7.0) */
# ifdef VIR_ENUM_SENTINELS
VIR_NETWORK_METADATA_LAST /* (Since: 9.7.0) */
# endif
} virNetworkMetadataType;
int
virNetworkSetMetadata(virNetworkPtr network,
int type,
const char *metadata,
const char *key,
const char *uri,
unsigned int flags);
char *
virNetworkGetMetadata(virNetworkPtr network,
int type,
const char *uri,
unsigned int flags);
#endif /* LIBVIRT_NETWORK_H */

View File

@ -348,6 +348,7 @@ typedef enum {
VIR_ERR_NO_HOSTNAME = 108, /* no domain's hostname found (Since: 6.1.0) */
VIR_ERR_CHECKPOINT_INCONSISTENT = 109, /* checkpoint can't be used (Since: 6.10.0) */
VIR_ERR_MULTIPLE_DOMAINS = 110, /* more than one matching domain found (Since: 7.1.0) */
VIR_ERR_NO_NETWORK_METADATA = 111, /* Network metadata is not present (Since: 9.7.0) */
# ifdef VIR_ENUM_SENTINELS
VIR_ERR_NUMBER_LAST /* (Since: 5.0.0) */

View File

@ -161,6 +161,20 @@ typedef int
virNetworkPortPtr **ports,
unsigned int flags);
typedef int
(*virDrvNetworkSetMetadata)(virNetworkPtr network,
int type,
const char *metadata,
const char *key,
const char *uri,
unsigned int flags);
typedef char *
(*virDrvNetworkGetMetadata)(virNetworkPtr network,
int type,
const char *uri,
unsigned int flags);
typedef struct _virNetworkDriver virNetworkDriver;
/**
@ -202,4 +216,6 @@ struct _virNetworkDriver {
virDrvNetworkPortGetParameters networkPortGetParameters;
virDrvNetworkPortDelete networkPortDelete;
virDrvNetworkListAllPorts networkListAllPorts;
virDrvNetworkSetMetadata networkSetMetadata;
virDrvNetworkGetMetadata networkGetMetadata;
};

View File

@ -1915,3 +1915,170 @@ virNetworkPortRef(virNetworkPortPtr port)
virObjectRef(port);
return 0;
}
/**
* virNetworkSetMetadata:
* @network: a network object
* @type: type of metadata, from virNetworkMetadataType
* @metadata: new metadata text
* @key: XML namespace key, or NULL
* @uri: XML namespace URI, or NULL
* @flags: bitwise-OR of virNetworkUpdateFlags
*
* Sets the appropriate network element given by @type to the
* value of @metadata. A @type of VIR_NETWORK_METADATA_DESCRIPTION
* is free-form text; VIR_NETWORK_METADATA_TITLE is free-form, but no
* newlines are permitted, and should be short (although the length is
* not enforced). For these two options @key and @uri are irrelevant and
* must be set to NULL.
*
* For type VIR_NETWORK_METADATA_ELEMENT @metadata must be well-formed
* XML belonging to namespace defined by @uri with local name @key.
*
* Passing NULL for @metadata says to remove that element from the
* network XML (passing the empty string leaves the element present).
*
* The resulting metadata will be present in virNetworkGetXMLDesc(),
* as well as quick access through virNetworkGetMetadata().
*
* @flags controls whether the live network state, persistent configuration,
* or both will be modified.
*
* Returns 0 on success, -1 in case of failure.
*
* Since: 9.7.0
*/
int
virNetworkSetMetadata(virNetworkPtr network,
int type,
const char *metadata,
const char *key,
const char *uri,
unsigned int flags)
{
virConnectPtr conn;
VIR_DEBUG("network=%p, type=%d, metadata='%s', key='%s', uri='%s', flags=0x%x",
network, type, NULLSTR(metadata), NULLSTR(key), NULLSTR(uri),
flags);
virResetLastError();
virCheckNetworkReturn(network, -1);
conn = network->conn;
virCheckReadOnlyGoto(conn->flags, error);
switch (type) {
case VIR_NETWORK_METADATA_TITLE:
if (metadata && strchr(metadata, '\n')) {
virReportInvalidArg(metadata, "%s",
_("metadata title can't contain "
"newlines"));
goto error;
}
G_GNUC_FALLTHROUGH;
case VIR_NETWORK_METADATA_DESCRIPTION:
virCheckNullArgGoto(uri, error);
virCheckNullArgGoto(key, error);
break;
case VIR_NETWORK_METADATA_ELEMENT:
virCheckNonNullArgGoto(uri, error);
if (metadata)
virCheckNonNullArgGoto(key, error);
break;
default:
/* For future expansion */
break;
}
if (conn->networkDriver->networkSetMetadata) {
int ret;
ret = conn->networkDriver->networkSetMetadata(network, type, metadata, key, uri,
flags);
if (ret < 0)
goto error;
return ret;
}
virReportUnsupportedError();
error:
virDispatchError(network->conn);
return -1;
}
/**
* virNetworkGetMetadata:
* @network: a network object
* @type: type of metadata, from virNetworkMetadataType
* @uri: XML namespace identifier
* @flags: bitwise-OR of virNetworkUpdateFlags
*
* Retrieves the appropriate network element given by @type.
* If VIR_NETWORK_METADATA_ELEMENT is requested parameter @uri
* must be set to the name of the namespace the requested elements
* belong to, otherwise must be NULL.
*
* If an element of the network XML is not present, the resulting
* error will be VIR_ERR_NO_NETWORK_METADATA. This method forms
* a shortcut for seeing information from virNetworkSetMetadata()
* without having to go through virNetworkGetXMLDesc().
*
* @flags controls whether the live network state or persistent
* configuration will be queried.
*
* Returns the metadata string on success (caller must free),
* or NULL in case of failure.
*
* Since: 9.7.0
*/
char *
virNetworkGetMetadata(virNetworkPtr network,
int type,
const char *uri,
unsigned int flags)
{
virConnectPtr conn;
VIR_DEBUG("network=%p, type=%d, uri='%s', flags=0x%x",
network, type, NULLSTR(uri), flags);
virResetLastError();
virCheckNetworkReturn(network, NULL);
VIR_EXCLUSIVE_FLAGS_GOTO(VIR_NETWORK_UPDATE_AFFECT_LIVE,
VIR_NETWORK_UPDATE_AFFECT_CONFIG,
error);
switch (type) {
case VIR_NETWORK_METADATA_TITLE:
case VIR_NETWORK_METADATA_DESCRIPTION:
virCheckNullArgGoto(uri, error);
break;
case VIR_NETWORK_METADATA_ELEMENT:
virCheckNonNullArgGoto(uri, error);
break;
default:
/* For future expansion */
break;
}
conn = network->conn;
if (conn->networkDriver->networkGetMetadata) {
char *ret;
if (!(ret = conn->networkDriver->networkGetMetadata(network, type, uri, flags)))
goto error;
return ret;
}
virReportUnsupportedError();
error:
virDispatchError(network->conn);
return NULL;
}

View File

@ -932,4 +932,10 @@ LIBVIRT_9.0.0 {
virDomainFDAssociate;
} LIBVIRT_8.5.0;
LIBVIRT_9.7.0 {
global:
virNetworkGetMetadata;
virNetworkSetMetadata;
} LIBVIRT_9.0.0;
# .... define new API here using predicted next version number ....

View File

@ -1287,6 +1287,9 @@ static const virErrorMsgTuple virErrorMsgStrings[] = {
[VIR_ERR_MULTIPLE_DOMAINS] = {
N_("multiple matching domains found"),
N_("multiple matching domains found: %1$s") },
[VIR_ERR_NO_NETWORK_METADATA] = {
N_("metadata not found"),
N_("metadata not found: %1$s") },
};
G_STATIC_ASSERT(G_N_ELEMENTS(virErrorMsgStrings) == VIR_ERR_NUMBER_LAST);