mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-05 04:25:19 +00:00
Introduce secret lifecycle event APIs
Add public APIs to allow applications to watch for define and undefine of secret objects. Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
This commit is contained in:
parent
89283c138e
commit
34fd3caabf
@ -110,5 +110,96 @@ int virSecretUndefine (virSecretPtr secret);
|
|||||||
int virSecretRef (virSecretPtr secret);
|
int virSecretRef (virSecretPtr secret);
|
||||||
int virSecretFree (virSecretPtr secret);
|
int virSecretFree (virSecretPtr secret);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* VIR_SECRET_EVENT_CALLBACK:
|
||||||
|
*
|
||||||
|
* Used to cast the event specific callback into the generic one
|
||||||
|
* for use for virConnectSecretEventRegisterAny()
|
||||||
|
*/
|
||||||
|
# define VIR_SECRET_EVENT_CALLBACK(cb)((virConnectSecretEventGenericCallback)(cb))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virSecretEventID:
|
||||||
|
*
|
||||||
|
* An enumeration of supported eventId parameters for
|
||||||
|
* virConnectSecretEventRegisterAny(). Each event id determines which
|
||||||
|
* signature of callback function will be used.
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
VIR_SECRET_EVENT_ID_LIFECYCLE = 0, /* virConnectSecretEventLifecycleCallback */
|
||||||
|
|
||||||
|
# ifdef VIR_ENUM_SENTINELS
|
||||||
|
VIR_SECRET_EVENT_ID_LAST
|
||||||
|
/*
|
||||||
|
* NB: this enum value will increase over time as new events are
|
||||||
|
* added to the libvirt API. It reflects the last event ID supported
|
||||||
|
* by this version of the libvirt API.
|
||||||
|
*/
|
||||||
|
# endif
|
||||||
|
} virSecretEventID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virConnectSecretEventGenericCallback:
|
||||||
|
* @conn: the connection pointer
|
||||||
|
* @secret: the secret pointer
|
||||||
|
* @opaque: application specified data
|
||||||
|
*
|
||||||
|
* A generic secret event callback handler, for use with
|
||||||
|
* virConnectSecretEventRegisterAny(). Specific events usually
|
||||||
|
* have a customization with extra parameters, often with @opaque being
|
||||||
|
* passed in a different parameter position; use
|
||||||
|
* VIR_SECRET_EVENT_CALLBACK() when registering an appropriate handler.
|
||||||
|
*/
|
||||||
|
typedef void (*virConnectSecretEventGenericCallback)(virConnectPtr conn,
|
||||||
|
virSecretPtr secret,
|
||||||
|
void *opaque);
|
||||||
|
|
||||||
|
/* Use VIR_SECRET_EVENT_CALLBACK() to cast the 'cb' parameter */
|
||||||
|
int virConnectSecretEventRegisterAny(virConnectPtr conn,
|
||||||
|
virSecretPtr secret, /* optional, to filter */
|
||||||
|
int eventID,
|
||||||
|
virConnectSecretEventGenericCallback cb,
|
||||||
|
void *opaque,
|
||||||
|
virFreeCallback freecb);
|
||||||
|
|
||||||
|
int virConnectSecretEventDeregisterAny(virConnectPtr conn,
|
||||||
|
int callbackID);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virSecretEventLifecycleType:
|
||||||
|
*
|
||||||
|
* a virSecretEventLifecycleType is emitted during secret
|
||||||
|
* lifecycle events
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
VIR_SECRET_EVENT_DEFINED = 0,
|
||||||
|
VIR_SECRET_EVENT_UNDEFINED = 1,
|
||||||
|
|
||||||
|
# ifdef VIR_ENUM_SENTINELS
|
||||||
|
VIR_SECRET_EVENT_LAST
|
||||||
|
# endif
|
||||||
|
} virSecretEventLifecycleType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virConnectSecretEventLifecycleCallback:
|
||||||
|
* @conn: connection object
|
||||||
|
* @secret: secret on which the event occurred
|
||||||
|
* @event: The specific virSecretEventLifeCycleType which occurred
|
||||||
|
* @detail: contains some details on the reason of the event.
|
||||||
|
* @opaque: application specified data
|
||||||
|
*
|
||||||
|
* This callback is called when a secret lifecycle action is performed,
|
||||||
|
* like added or removed.
|
||||||
|
*
|
||||||
|
* The callback signature to use when registering for an event of type
|
||||||
|
* VIR_SECRET_EVENT_ID_LIFECYCLE with
|
||||||
|
* virConnectSecretEventRegisterAny()
|
||||||
|
*/
|
||||||
|
typedef void (*virConnectSecretEventLifecycleCallback)(virConnectPtr conn,
|
||||||
|
virSecretPtr secret,
|
||||||
|
int event,
|
||||||
|
int detail,
|
||||||
|
void *opaque);
|
||||||
|
|
||||||
|
|
||||||
#endif /* __VIR_LIBVIRT_SECRET_H__ */
|
#endif /* __VIR_LIBVIRT_SECRET_H__ */
|
||||||
|
@ -223,6 +223,20 @@ extern virClassPtr virAdmClientClass;
|
|||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
# define virCheckSecretGoto(obj, label) \
|
||||||
|
do { \
|
||||||
|
virSecretPtr _secret = (obj); \
|
||||||
|
if (!virObjectIsClass(_secret, virSecretClass) || \
|
||||||
|
!virObjectIsClass(_secret->conn, virConnectClass)) { \
|
||||||
|
virReportErrorHelper(VIR_FROM_SECRET, \
|
||||||
|
VIR_ERR_INVALID_SECRET, \
|
||||||
|
__FILE__, __FUNCTION__, __LINE__, \
|
||||||
|
__FUNCTION__); \
|
||||||
|
virDispatchError(NULL); \
|
||||||
|
goto label; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
# define virCheckStreamReturn(obj, retval) \
|
# define virCheckStreamReturn(obj, retval) \
|
||||||
do { \
|
do { \
|
||||||
virStreamPtr _st = (obj); \
|
virStreamPtr _st = (obj); \
|
||||||
|
@ -77,6 +77,18 @@ typedef int
|
|||||||
virSecretPtr **secrets,
|
virSecretPtr **secrets,
|
||||||
unsigned int flags);
|
unsigned int flags);
|
||||||
|
|
||||||
|
typedef int
|
||||||
|
(*virDrvConnectSecretEventRegisterAny)(virConnectPtr conn,
|
||||||
|
virSecretPtr secret,
|
||||||
|
int eventID,
|
||||||
|
virConnectSecretEventGenericCallback cb,
|
||||||
|
void *opaque,
|
||||||
|
virFreeCallback freecb);
|
||||||
|
|
||||||
|
typedef int
|
||||||
|
(*virDrvConnectSecretEventDeregisterAny)(virConnectPtr conn,
|
||||||
|
int callbackID);
|
||||||
|
|
||||||
typedef struct _virSecretDriver virSecretDriver;
|
typedef struct _virSecretDriver virSecretDriver;
|
||||||
typedef virSecretDriver *virSecretDriverPtr;
|
typedef virSecretDriver *virSecretDriverPtr;
|
||||||
|
|
||||||
@ -98,6 +110,8 @@ struct _virSecretDriver {
|
|||||||
virDrvSecretSetValue secretSetValue;
|
virDrvSecretSetValue secretSetValue;
|
||||||
virDrvSecretGetValue secretGetValue;
|
virDrvSecretGetValue secretGetValue;
|
||||||
virDrvSecretUndefine secretUndefine;
|
virDrvSecretUndefine secretUndefine;
|
||||||
|
virDrvConnectSecretEventRegisterAny connectSecretEventRegisterAny;
|
||||||
|
virDrvConnectSecretEventDeregisterAny connectSecretEventDeregisterAny;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -693,3 +693,132 @@ virSecretFree(virSecretPtr secret)
|
|||||||
virObjectUnref(secret);
|
virObjectUnref(secret);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virConnectSecretEventRegisterAny:
|
||||||
|
* @conn: pointer to the connection
|
||||||
|
* @secret: pointer to the secret
|
||||||
|
* @eventID: the event type to receive
|
||||||
|
* @cb: callback to the function handling secret events
|
||||||
|
* @opaque: opaque data to pass on to the callback
|
||||||
|
* @freecb: optional function to deallocate opaque when not used anymore
|
||||||
|
*
|
||||||
|
* Adds a callback to receive notifications of arbitrary secret events
|
||||||
|
* occurring on a secret. This function requires that an event loop
|
||||||
|
* has been previously registered with virEventRegisterImpl() or
|
||||||
|
* virEventRegisterDefaultImpl().
|
||||||
|
*
|
||||||
|
* If @secret is NULL, then events will be monitored for any secret.
|
||||||
|
* If @secret is non-NULL, then only the specific secret will be monitored.
|
||||||
|
*
|
||||||
|
* Most types of events have a callback providing a custom set of parameters
|
||||||
|
* for the event. When registering an event, it is thus necessary to use
|
||||||
|
* the VIR_SECRET_EVENT_CALLBACK() macro to cast the
|
||||||
|
* supplied function pointer to match the signature of this method.
|
||||||
|
*
|
||||||
|
* The virSecretPtr object handle passed into the callback upon delivery
|
||||||
|
* of an event is only valid for the duration of execution of the callback.
|
||||||
|
* If the callback wishes to keep the secret object after the callback
|
||||||
|
* returns, it shall take a reference to it, by calling virSecretRef().
|
||||||
|
* The reference can be released once the object is no longer required
|
||||||
|
* by calling virSecretFree().
|
||||||
|
*
|
||||||
|
* The return value from this method is a positive integer identifier
|
||||||
|
* for the callback. To unregister a callback, this callback ID should
|
||||||
|
* be passed to the virConnectSecretEventDeregisterAny() method.
|
||||||
|
*
|
||||||
|
* Returns a callback identifier on success, -1 on failure.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
virConnectSecretEventRegisterAny(virConnectPtr conn,
|
||||||
|
virSecretPtr secret,
|
||||||
|
int eventID,
|
||||||
|
virConnectSecretEventGenericCallback cb,
|
||||||
|
void *opaque,
|
||||||
|
virFreeCallback freecb)
|
||||||
|
{
|
||||||
|
VIR_DEBUG("conn=%p, secret=%p, eventID=%d, cb=%p, opaque=%p, freecb=%p",
|
||||||
|
conn, secret, eventID, cb, opaque, freecb);
|
||||||
|
|
||||||
|
virResetLastError();
|
||||||
|
|
||||||
|
virCheckConnectReturn(conn, -1);
|
||||||
|
if (secret) {
|
||||||
|
virCheckSecretGoto(secret, error);
|
||||||
|
if (secret->conn != conn) {
|
||||||
|
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
||||||
|
virUUIDFormat(secret->uuid, uuidstr);
|
||||||
|
virReportInvalidArg(secret,
|
||||||
|
_("secret '%s' in %s must match connection"),
|
||||||
|
uuidstr, __FUNCTION__);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
virCheckNonNullArgGoto(cb, error);
|
||||||
|
virCheckNonNegativeArgGoto(eventID, error);
|
||||||
|
|
||||||
|
if (eventID >= VIR_SECRET_EVENT_ID_LAST) {
|
||||||
|
virReportInvalidArg(eventID,
|
||||||
|
_("eventID in %s must be less than %d"),
|
||||||
|
__FUNCTION__, VIR_SECRET_EVENT_ID_LAST);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (conn->secretDriver &&
|
||||||
|
conn->secretDriver->connectSecretEventRegisterAny) {
|
||||||
|
int ret;
|
||||||
|
ret = conn->secretDriver->connectSecretEventRegisterAny(conn,
|
||||||
|
secret,
|
||||||
|
eventID,
|
||||||
|
cb,
|
||||||
|
opaque,
|
||||||
|
freecb);
|
||||||
|
if (ret < 0)
|
||||||
|
goto error;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
virReportUnsupportedError();
|
||||||
|
error:
|
||||||
|
virDispatchError(conn);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virConnectSecretEventDeregisterAny:
|
||||||
|
* @conn: pointer to the connection
|
||||||
|
* @callbackID: the callback identifier
|
||||||
|
*
|
||||||
|
* Removes an event callback. The callbackID parameter should be the
|
||||||
|
* value obtained from a previous virConnectSecretEventRegisterAny() method.
|
||||||
|
*
|
||||||
|
* Returns 0 on success, -1 on failure.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
virConnectSecretEventDeregisterAny(virConnectPtr conn,
|
||||||
|
int callbackID)
|
||||||
|
{
|
||||||
|
VIR_DEBUG("conn=%p, callbackID=%d", conn, callbackID);
|
||||||
|
|
||||||
|
virResetLastError();
|
||||||
|
|
||||||
|
virCheckConnectReturn(conn, -1);
|
||||||
|
virCheckNonNegativeArgGoto(callbackID, error);
|
||||||
|
|
||||||
|
if (conn->secretDriver &&
|
||||||
|
conn->secretDriver->connectSecretEventDeregisterAny) {
|
||||||
|
int ret;
|
||||||
|
ret = conn->secretDriver->connectSecretEventDeregisterAny(conn,
|
||||||
|
callbackID);
|
||||||
|
if (ret < 0)
|
||||||
|
goto error;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
virReportUnsupportedError();
|
||||||
|
error:
|
||||||
|
virDispatchError(conn);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
@ -749,6 +749,8 @@ LIBVIRT_2.2.0 {
|
|||||||
LIBVIRT_3.0.0 {
|
LIBVIRT_3.0.0 {
|
||||||
global:
|
global:
|
||||||
virStorageVolGetInfoFlags;
|
virStorageVolGetInfoFlags;
|
||||||
|
virConnectSecretEventRegisterAny;
|
||||||
|
virConnectSecretEventDeregisterAny;
|
||||||
} LIBVIRT_2.2.0;
|
} LIBVIRT_2.2.0;
|
||||||
|
|
||||||
# .... define new API here using predicted next version number ....
|
# .... define new API here using predicted next version number ....
|
||||||
|
Loading…
Reference in New Issue
Block a user