mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-03-20 07:59:00 +00:00
secrets: add support for running secret driver in embedded mode
This enables support for running the secret driver embedded to the calling application process using a URI: secret:///embed?root=/some/path When using the embedded mode with a root=/var/tmp/embed, the driver will use the following paths: configDir: /var/tmp/embed/etc/secrets stateDir: /var/tmp/embed/run/secrets These are identical whether the embedded driver is privileged or unprivileged. This compares with the system instance which uses configDir: /etc/libvirt/secrets stateDir: /var/lib/libvirt/secrets When an embedded instance of the secret driver is open, any other embedded drivers will automatically use the embedded secret driver. Reviewed-by: Michal Privoznik <mprivozn@redhat.com> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
parent
068efae5b1
commit
3e9076e777
@ -8,6 +8,7 @@
|
||||
<li><a href="#hypervisor">Hypervisor drivers</a></li>
|
||||
<li><a href="storage.html">Storage drivers</a></li>
|
||||
<li><a href="drvnodedev.html">Node device driver</a></li>
|
||||
<li><a href="drvsecret.html">Secret driver</a></li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
|
82
docs/drvsecret.html.in
Normal file
82
docs/drvsecret.html.in
Normal file
@ -0,0 +1,82 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<body>
|
||||
<h1>Secret information management</h1>
|
||||
|
||||
<p>
|
||||
The secrets driver in libvirt provides a simple interface for
|
||||
storing and retrieving secret information.
|
||||
</p>
|
||||
|
||||
<h2><a id="uris">Connections to SECRET driver</a></h2>
|
||||
|
||||
<p>
|
||||
The libvirt SECRET driver is a multi-instance driver, providing a single
|
||||
system wide privileged driver (the "system" instance), and per-user
|
||||
unprivileged drivers (the "session" instance). A connection to the secret
|
||||
driver is automatically available when opening a connection to one of the
|
||||
stateful primary hypervisor drivers. It is none the less also possible to
|
||||
explicitly open just the secret driver, using the URI protocol "secret"
|
||||
Some example connection URIs for the driver are:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
secret:///session (local access to per-user instance)
|
||||
secret+unix:///session (local access to per-user instance)
|
||||
|
||||
secret:///system (local access to system instance)
|
||||
secret+unix:///system (local access to system instance)
|
||||
secret://example.com/system (remote access, TLS/x509)
|
||||
secret+tcp://example.com/system (remote access, SASl/Kerberos)
|
||||
secret+ssh://root@example.com/system (remote access, SSH tunnelled)
|
||||
</pre>
|
||||
|
||||
<h3><a id="uriembedded">Embedded driver</a></h3>
|
||||
|
||||
<p>
|
||||
Since 6.0.0 the secret driver has experimental support for operating
|
||||
in an embedded mode. In this scenario, rather than connecting to
|
||||
the libvirtd daemon, the secret driver runs in the client application
|
||||
process directly. To open the driver in embedded mode the app use the
|
||||
new URI path and specify a virtual root directory under which the
|
||||
driver will create content.
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
secret:///embed?root=/some/dir
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
Under the specified root directory the following locations will
|
||||
be used
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
/some/dir
|
||||
|
|
||||
+- etc
|
||||
| |
|
||||
| +- secrets
|
||||
|
|
||||
+- run
|
||||
|
|
||||
+- secrets
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
The application is responsible for recursively purging the contents
|
||||
of this directory tree once they no longer require a connection,
|
||||
though it can also be left intact for reuse when opening a future
|
||||
connection.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The range of functionality is intended to be on a par with that
|
||||
seen when using the traditional system or session libvirt connections
|
||||
to QEMU. Normal practice would be to open the secret driver in embedded
|
||||
mode any time one of the other drivers is opened in embedded mode so
|
||||
that the two drivers can interact in-process.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
@ -55,6 +55,8 @@ typedef virSecretDriverState *virSecretDriverStatePtr;
|
||||
struct _virSecretDriverState {
|
||||
virMutex lock;
|
||||
bool privileged; /* readonly */
|
||||
char *embeddedRoot; /* readonly */
|
||||
int embeddedRefs;
|
||||
virSecretObjListPtr secrets;
|
||||
char *stateDir;
|
||||
char *configDir;
|
||||
@ -456,12 +458,6 @@ secretStateInitialize(bool privileged,
|
||||
virStateInhibitCallback callback G_GNUC_UNUSED,
|
||||
void *opaque G_GNUC_UNUSED)
|
||||
{
|
||||
if (root != NULL) {
|
||||
virReportError(VIR_ERR_INVALID_ARG, "%s",
|
||||
_("Driver does not support embedded mode"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (VIR_ALLOC(driver) < 0)
|
||||
return VIR_DRV_STATE_INIT_ERROR;
|
||||
|
||||
@ -475,7 +471,11 @@ secretStateInitialize(bool privileged,
|
||||
driver->secretEventState = virObjectEventStateNew();
|
||||
driver->privileged = privileged;
|
||||
|
||||
if (privileged) {
|
||||
if (root) {
|
||||
driver->embeddedRoot = g_strdup(root);
|
||||
driver->configDir = g_strdup_printf("%s/etc/secrets", root);
|
||||
driver->stateDir = g_strdup_printf("%s/run/secrets", root);
|
||||
} else if (privileged) {
|
||||
driver->configDir = g_strdup_printf("%s/libvirt/secrets", SYSCONFDIR);
|
||||
driver->stateDir = g_strdup_printf("%s/libvirt/secrets", RUNSTATEDIR);
|
||||
} else {
|
||||
@ -550,19 +550,54 @@ secretConnectOpen(virConnectPtr conn,
|
||||
return VIR_DRV_OPEN_ERROR;
|
||||
}
|
||||
|
||||
if (!virConnectValidateURIPath(conn->uri->path,
|
||||
"secret",
|
||||
driver->privileged))
|
||||
return VIR_DRV_OPEN_ERROR;
|
||||
if (driver->embeddedRoot) {
|
||||
const char *root = virURIGetParam(conn->uri, "root");
|
||||
if (!root)
|
||||
return VIR_DRV_OPEN_ERROR;
|
||||
|
||||
if (STRNEQ(conn->uri->path, "/embed")) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("URI must be secret:///embed"));
|
||||
return VIR_DRV_OPEN_ERROR;
|
||||
}
|
||||
|
||||
if (STRNEQ(root, driver->embeddedRoot)) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("Cannot open embedded driver at path '%s', "
|
||||
"already open with path '%s'"),
|
||||
root, driver->embeddedRoot);
|
||||
return VIR_DRV_OPEN_ERROR;
|
||||
}
|
||||
} else {
|
||||
if (!virConnectValidateURIPath(conn->uri->path,
|
||||
"secret",
|
||||
driver->privileged))
|
||||
return VIR_DRV_OPEN_ERROR;
|
||||
}
|
||||
|
||||
if (virConnectOpenEnsureACL(conn) < 0)
|
||||
return VIR_DRV_OPEN_ERROR;
|
||||
|
||||
if (driver->embeddedRoot) {
|
||||
secretDriverLock();
|
||||
if (driver->embeddedRefs == 0)
|
||||
virSetConnectSecret(conn);
|
||||
driver->embeddedRefs++;
|
||||
secretDriverUnlock();
|
||||
}
|
||||
|
||||
return VIR_DRV_OPEN_SUCCESS;
|
||||
}
|
||||
|
||||
static int secretConnectClose(virConnectPtr conn G_GNUC_UNUSED)
|
||||
{
|
||||
if (driver->embeddedRoot) {
|
||||
secretDriverLock();
|
||||
driver->embeddedRefs--;
|
||||
if (driver->embeddedRefs == 0)
|
||||
virSetConnectSecret(NULL);
|
||||
secretDriverUnlock();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -655,6 +690,7 @@ static virHypervisorDriver secretHypervisorDriver = {
|
||||
static virConnectDriver secretConnectDriver = {
|
||||
.localOnly = true,
|
||||
.uriSchemes = (const char *[]){ "secret", NULL },
|
||||
.embeddable = true,
|
||||
.hypervisorDriver = &secretHypervisorDriver,
|
||||
.secretDriver = &secretDriver,
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user