[libvirt PATCH v3 2/8] Metadata change APIs and related enums

K Shiva shiva_kr at riseup.net
Mon Jun 26 13:55:17 UTC 2023


Added:
- virNetworkGetMetadata() and virNetworkSetMetadata() APIs.
- enums representing metadata type, i.e title, description or
  custom metadata.
- enum representing metadata change callback event.

Signed-off-by: K Shiva <shiva_kr at riseup.net>
---
 include/libvirt/libvirt-network.h |  51 +++++++++
 src/libvirt-network.c             | 167 ++++++++++++++++++++++++++++++
 src/libvirt_public.syms           |   6 ++
 3 files changed, 224 insertions(+)

diff --git a/include/libvirt/libvirt-network.h b/include/libvirt/libvirt-network.h
index 90cde0cf24..e5d25d699b 100644
--- a/include/libvirt/libvirt-network.h
+++ b/include/libvirt/libvirt-network.h
@@ -330,6 +330,7 @@ typedef void (*virConnectNetworkEventLifecycleCallback)(virConnectPtr conn,
  */
 typedef enum {
     VIR_NETWORK_EVENT_ID_LIFECYCLE = 0,       /* virConnectNetworkEventLifecycleCallback (Since: 1.2.1) */
+    VIR_NETWORK_EVENT_ID_METADATA_CHANGE = 1, /* virConnectNetworkEventMetadataChangeCallback (Since: 9.5.0) */
 
 # ifdef VIR_ENUM_SENTINELS
     VIR_NETWORK_EVENT_ID_LAST
@@ -547,4 +548,54 @@ virNetworkPortFree(virNetworkPortPtr port);
 int
 virNetworkPortRef(virNetworkPortPtr port);
 
+/**
+ * virNetworkMetadataType:
+ *
+ * Since: 9.5.0
+ */
+typedef enum {
+    VIR_NETWORK_METADATA_DESCRIPTION = 0, /* Operate on <description> (Since: 9.5.0) */
+    VIR_NETWORK_METADATA_TITLE       = 1, /* Operate on <title> (Since: 9.5.0) */
+    VIR_NETWORK_METADATA_ELEMENT     = 2, /* Operate on <metadata> (Since: 9.5.0) */
+
+# ifdef VIR_ENUM_SENTINELS
+    VIR_NETWORK_METADATA_LAST /* (Since: 9.5.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);
+
+/**
+ * virConnectNetworkEventMetadataChangeCallback:
+ * @conn: connection object
+ * @net: network on which the event occurred
+ * @type: a value from virNetworkMetadataType
+ * @nsuri: XML namespace URI
+ * @opaque: application specified data
+ *
+ * This callback is triggered when the network XML metadata is changed
+ *
+ * The callback signature to use when registering for an event of type
+ * VIR_NETWORK_EVENT_ID_METADATA_CHANGE with virConnectNetworkEventRegisterAny().
+ *
+ * Since: 9.5.0
+ */
+typedef void (*virConnectNetworkEventMetadataChangeCallback)(virConnectPtr conn,
+                                                            virNetworkPtr net,
+                                                            int type,
+                                                            const char *nsuri,
+                                                            void *opaque);
+
 #endif /* LIBVIRT_NETWORK_H */
diff --git a/src/libvirt-network.c b/src/libvirt-network.c
index 236dfe2f5d..c0c66bb2fa 100644
--- a/src/libvirt-network.c
+++ b/src/libvirt-network.c
@@ -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.5.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.5.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;
+}
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index 80742f268e..d21fe49caa 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -932,4 +932,10 @@ LIBVIRT_9.0.0 {
         virDomainFDAssociate;
 } LIBVIRT_8.5.0;
 
+LIBVIRT_9.5.0 {
+    global:
+        virNetworkGetMetadata;
+        virNetworkSetMetadata;
+} LIBVIRT_9.0.0;
+
 # .... define new API here using predicted next version number ....
-- 
2.41.0



More information about the libvir-list mailing list