This patch adds a "secret" as a separately managed object, using a
special-purpose API to transfer the secret values between nodes and
libvirt users.
Rather than add explicit accessors for attributes of secrets, and
hard-code the "secrets are related to storage volumes" association in
the API, the API uses XML to manipulate the association as well as
other attributes, similarly to other areas of libvirt.
The user can set attributes of the secret using XML, e.g.
<secret ephemeral='no' private='yes'>
<uuid>b8eecf55-798e-4db7-b2dd-025b0cf08a36</uuid>
<volume>/var/lib/libvirt/images/mail.img</volume>
<description>LUKS passphrase for our mail server</description>
</secret>
If <uuid/> is not specified, it is chosen automatically.
The secret value can be either generated and stored by libvirt during
volume creation, or supplied by the user using virSecretSetValue().
A simple API is provided for enumeration of all secrets. Very large
deployments will manage secret IDs automatically, so it is probably not
necessary to provide a specialized lookup function (allowing the volume
key -> secret ID lookup in less than O(number of secrets)). These
functions can eventually be added later.
Changes since the second submission:
- Changed API to revolve around a virSecretPtr. The operations are now:
virSecretGetConnect
virConnectNumOfSecrets
virConnectListSecrets
virSecretLookupByUUIDString
virSecretDefineXML
virSecretGetUUIDString
virSecretGetXMLDesc
virSecretSetValue
virSecretGetValue
virSecretUndefine
virSecretRef
virSecretFree
- Use an optional <uuid/> element inside <secret/> to pre-specify an
UUID in virSecretDefineXML() (default is to choose an UUID
automatically)
- s/secret_id/uuid/g
- use "unsigned char *" for secret value
- Use "Secret XML" instead of "Secret attributes XML" in the HTML
documentation now that the XML contains the UUID as well.
---
docs/format.html | 4 +
docs/formatcaps.html | 4 +
docs/formatdomain.html | 4 +
docs/formatnetwork.html | 4 +
docs/formatnode.html | 4 +
docs/formatsecret.html | 170 ++++++++++++++++++++++++++++++++++++++++++
docs/formatsecret.html.in | 52 +++++++++++++
docs/formatstorage.html | 4 +
docs/schemas/Makefile.am | 1 +
docs/schemas/secret.rng | 44 +++++++++++
docs/sitemap.html | 3 +
docs/sitemap.html.in | 4 +
include/libvirt/libvirt.h | 34 +++++++++
include/libvirt/libvirt.h.in | 34 +++++++++
src/libvirt_public.syms | 16 ++++
15 files changed, 382 insertions(+), 0 deletions(-)
create mode 100644 docs/formatsecret.html
create mode 100644 docs/formatsecret.html.in
create mode 100644 docs/schemas/secret.rng
diff --git a/docs/format.html b/docs/format.html
index e97d0e7..3c20b5f 100644
--- a/docs/format.html
+++ b/docs/format.html
@@ -70,6 +70,10 @@
<div>
<a title="The host device XML format"
class="inactive" href="formatnode.html">Node Devices</a>
</div>
+ </li><li>
+ <div>
+ <a title="The secret XML format"
class="inactive" href="formatsecret.html">Secrets</a>
+ </div>
</li></ul>
</div>
</li><li>
diff --git a/docs/formatcaps.html b/docs/formatcaps.html
index 5b20aac..5f2bc72 100644
--- a/docs/formatcaps.html
+++ b/docs/formatcaps.html
@@ -70,6 +70,10 @@
<div>
<a title="The host device XML format"
class="inactive" href="formatnode.html">Node Devices</a>
</div>
+ </li><li>
+ <div>
+ <a title="The secret XML format"
class="inactive" href="formatsecret.html">Secrets</a>
+ </div>
</li></ul>
</div>
</li><li>
diff --git a/docs/formatdomain.html b/docs/formatdomain.html
index 5415200..6b655ad 100644
--- a/docs/formatdomain.html
+++ b/docs/formatdomain.html
@@ -70,6 +70,10 @@
<div>
<a title="The host device XML format"
class="inactive" href="formatnode.html">Node Devices</a>
</div>
+ </li><li>
+ <div>
+ <a title="The secret XML format"
class="inactive" href="formatsecret.html">Secrets</a>
+ </div>
</li></ul>
</div>
</li><li>
diff --git a/docs/formatnetwork.html b/docs/formatnetwork.html
index 0b25a0b..72a3cda 100644
--- a/docs/formatnetwork.html
+++ b/docs/formatnetwork.html
@@ -70,6 +70,10 @@
<div>
<a title="The host device XML format"
class="inactive" href="formatnode.html">Node Devices</a>
</div>
+ </li><li>
+ <div>
+ <a title="The secret XML format"
class="inactive" href="formatsecret.html">Secrets</a>
+ </div>
</li></ul>
</div>
</li><li>
diff --git a/docs/formatnode.html b/docs/formatnode.html
index 4d30b0c..516c27b 100644
--- a/docs/formatnode.html
+++ b/docs/formatnode.html
@@ -70,6 +70,10 @@
<div>
<span class="active">Node Devices</span>
</div>
+ </li><li>
+ <div>
+ <a title="The secret XML format"
class="inactive" href="formatsecret.html">Secrets</a>
+ </div>
</li></ul>
</div>
</li><li>
diff --git a/docs/formatsecret.html b/docs/formatsecret.html
new file mode 100644
index 0000000..998e874
--- /dev/null
+++ b/docs/formatsecret.html
@@ -0,0 +1,170 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html
xmlns="http://www.w3.org/1999/xhtml">
+<!--
+ This file is autogenerated from formatsecret.html.in
+ Do not edit this file. Changes will be lost.
+ -->
+ <head>
+ <meta http-equiv="Content-Type" content="text/html;
charset=ISO-8859-1" />
+ <link rel="stylesheet" type="text/css"
href="main.css" />
+ <link rel="SHORTCUT ICON" href="32favicon.png" />
+ <title>libvirt: Secret XML format</title>
+ <meta name="description" content="libvirt, virtualization,
virtualization API" />
+ </head>
+ <body>
+ <div id="header">
+ <div id="headerLogo"></div>
+ <div id="headerSearch">
+ <form action="search.php"
enctype="application/x-www-form-urlencoded"
method="get"><div>
+ <input id="query" name="query" type="text"
size="12" value="" />
+ <input id="submit" name="submit"
type="submit" value="Search" />
+ </div></form>
+ </div>
+ </div>
+ <div id="body">
+ <div id="menu">
+ <ul class="l0"><li>
+ <div>
+ <a title="Front page of the libvirt website"
class="inactive" href="index.html">Home</a>
+ </div>
+ </li><li>
+ <div>
+ <a title="Details of new features and bugs fixed in each
release" class="inactive" href="news.html">News</a>
+ </div>
+ </li><li>
+ <div>
+ <a title="Get the latest source releases, binary builds and get
access to the source repository" class="inactive"
href="downloads.html">Downloads</a>
+ </div>
+ </li><li>
+ <div>
+ <a title="Information for users, administrators and
developers" class="active"
href="docs.html">Documentation</a>
+ <ul class="l1"><li>
+ <div>
+ <a title="Information about deploying and using libvirt"
class="inactive" href="deployment.html">Deployment</a>
+ </div>
+ </li><li>
+ <div>
+ <a title="Overview of the logical subsystems in the libvirt
API" class="inactive"
href="intro.html">Architecture</a>
+ </div>
+ </li><li>
+ <div>
+ <a title="Description of the XML formats used in
libvirt" class="active" href="format.html">XML
format</a>
+ <ul class="l2"><li>
+ <div>
+ <a title="The domain XML format"
class="inactive" href="formatdomain.html">Domains</a>
+ </div>
+ </li><li>
+ <div>
+ <a title="The virtual network XML format"
class="inactive" href="formatnetwork.html">Networks</a>
+ </div>
+ </li><li>
+ <div>
+ <a title="The storage pool and volume XML format"
class="inactive" href="formatstorage.html">Storage</a>
+ </div>
+ </li><li>
+ <div>
+ <a title="The driver capabilities XML format"
class="inactive" href="formatcaps.html">Capabilities</a>
+ </div>
+ </li><li>
+ <div>
+ <a title="The host device XML format"
class="inactive" href="formatnode.html">Node Devices</a>
+ </div>
+ </li><li>
+ <div>
+ <span class="active">Secrets</span>
+ </div>
+ </li></ul>
+ </div>
+ </li><li>
+ <div>
+ <a title="Hypervisor specific driver information"
class="inactive" href="drivers.html">Drivers</a>
+ </div>
+ </li><li>
+ <div>
+ <a title="Reference manual for the C public API"
class="inactive" href="html/index.html">API reference</a>
+ </div>
+ </li><li>
+ <div>
+ <a title="Bindings of the libvirt API for other
languages" class="inactive" href="bindings.html">Language
bindings</a>
+ </div>
+ </li><li>
+ <div>
+ <a title="Working on the internals of libvirt API, driver and
daemon code" class="inactive"
href="internals.html">Internals</a>
+ </div>
+ </li></ul>
+ </div>
+ </li><li>
+ <div>
+ <a title="User contributed content" class="inactive"
href="http://wiki.libvirt.org">Wiki</a>
+ </div>
+ </li><li>
+ <div>
+ <a title="Frequently asked questions"
class="inactive" href="FAQ.html">FAQ</a>
+ </div>
+ </li><li>
+ <div>
+ <a title="How and where to report bugs and request features"
class="inactive" href="bugs.html">Bug reports</a>
+ </div>
+ </li><li>
+ <div>
+ <a title="How to contact the developers via email and IRC"
class="inactive" href="contact.html">Contact</a>
+ </div>
+ </li><li>
+ <div>
+ <a title="Miscellaneous links of interest related to libvirt"
class="inactive" href="relatedlinks.html">Related Links</a>
+ </div>
+ </li><li>
+ <div>
+ <a title="Overview of all content on the website"
class="inactive" href="sitemap.html">Sitemap</a>
+ </div>
+ </li></ul>
+ </div>
+ <div id="content">
+ <h1>Secret XML format</h1>
+ <ul><li>
+ <a href="#SecretAttributes">Secret XML</a>
+ </li><li>
+ <a href="#example">Example</a>
+ </li></ul>
+ <h2>
+ <a name="SecretAttributes"
id="SecretAttributes">Secret XML</a>
+ </h2>
+ <p>
+ Secrets stored by libvirt may have attributes associated with them, using
+ the <code>secret</code> element. The <code>secret</code>
element has two
+ optional attributes, each with values '<code>yes</code>' and
+ '<code>no</code>', and defaulting to
'<code>no</code>':
+ </p>
+ <dl><dt><code>ephemeral</code></dt><dd>This
secret must only be kept in memory, never stored persistently.
+ </dd><dt><code>private</code></dt><dd>The value
of the secret must not be revealed to any caller of libvirt,
+ nor to any other node.
+ </dd></dl>
+ <p>
+ The top-level <code>secret</code> element may contain the following
+ elements:
+ </p>
+ <dl><dt><code>uuid</code></dt><dd>
+ An unique identifier for this secret (not necessarily in the UUID
+ format). If omitted when defining a new secret, a random UUID is
+ generated.
+ </dd><dt><code>volume</code></dt><dd>Key of a
volume this secret is associated with. It is safe to delete
+ the secret after the volume is deleted.
+ </dd><dt><code>description</code></dt><dd>A
human-readable description of the purpose of the secret.
+ </dd></dl>
+ <h2>
+ <a name="example" id="example">Example</a>
+ </h2>
+ <pre>
+ <secret ephemeral='no' private='yes'>
+ <volume>/var/lib/libvirt/images/mail.img</volume>
+ <description>LUKS passphrase for the main hard drive of our mail
server</description>
+ </secret></pre>
+ </div>
+ </div>
+ <div id="footer">
+ <p id="sponsor">
+ Sponsored by:<br /><a
href="http://et.redhat.com/"><img
src="et.png" alt="Project sponsored by Red Hat Emerging Technology"
/></a></p>
+ </div>
+ </body>
+</html>
diff --git a/docs/formatsecret.html.in b/docs/formatsecret.html.in
new file mode 100644
index 0000000..7471bf7
--- /dev/null
+++ b/docs/formatsecret.html.in
@@ -0,0 +1,52 @@
+<html>
+ <body>
+ <h1>Secret XML format</h1>
+
+ <ul id="toc"></ul>
+
+ <h2><a name="SecretAttributes">Secret XML</a></h2>
+
+ <p>
+ Secrets stored by libvirt may have attributes associated with them, using
+ the <code>secret</code> element. The <code>secret</code>
element has two
+ optional attributes, each with values '<code>yes</code>' and
+ '<code>no</code>', and defaulting to
'<code>no</code>':
+ </p>
+ <dl>
+ <dt><code>ephemeral</code></dt>
+ <dd>This secret must only be kept in memory, never stored persistently.
+ </dd>
+ <dt><code>private</code></dt>
+ <dd>The value of the secret must not be revealed to any caller of libvirt,
+ nor to any other node.
+ </dd>
+ </dl>
+ <p>
+ The top-level <code>secret</code> element may contain the following
+ elements:
+ </p>
+ <dl>
+ <dt><code>uuid</code></dt>
+ <dd>
+ An unique identifier for this secret (not necessarily in the UUID
+ format). If omitted when defining a new secret, a random UUID is
+ generated.
+ </dd>
+ <dt><code>volume</code></dt>
+ <dd>Key of a volume this secret is associated with. It is safe to delete
+ the secret after the volume is deleted.
+ </dd>
+ <dt><code>description</code></dt>
+ <dd>A human-readable description of the purpose of the secret.
+ </dd>
+ </dl>
+
+ <h2><a name="example">Example</a></h2>
+
+ <pre>
+ <secret ephemeral='no' private='yes'>
+ <volume>/var/lib/libvirt/images/mail.img</volume>
+ <description>LUKS passphrase for the main hard drive of our mail
server</description>
+ </secret></pre>
+ </body>
+</html>
diff --git a/docs/formatstorage.html b/docs/formatstorage.html
index 91e63b4..02cbcac 100644
--- a/docs/formatstorage.html
+++ b/docs/formatstorage.html
@@ -70,6 +70,10 @@
<div>
<a title="The host device XML format"
class="inactive" href="formatnode.html">Node Devices</a>
</div>
+ </li><li>
+ <div>
+ <a title="The secret XML format"
class="inactive" href="formatsecret.html">Secrets</a>
+ </div>
</li></ul>
</div>
</li><li>
diff --git a/docs/schemas/Makefile.am b/docs/schemas/Makefile.am
index ef41a63..a064518 100644
--- a/docs/schemas/Makefile.am
+++ b/docs/schemas/Makefile.am
@@ -5,6 +5,7 @@ schema_DATA = \
domain.rng \
interface.rng \
network.rng \
+ secret.rng \
storagepool.rng \
storagevol.rng \
nodedev.rng \
diff --git a/docs/schemas/secret.rng b/docs/schemas/secret.rng
new file mode 100644
index 0000000..05e04f2
--- /dev/null
+++ b/docs/schemas/secret.rng
@@ -0,0 +1,44 @@
+<!-- A Relax NG schema for the libvirt secret properties XML format -->
+<grammar
xmlns="http://relaxng.org/ns/structure/1.0">
+ <start>
+ <ref name='secret'/>
+ </start>
+
+ <define name='secret'>
+ <element name='secret'>
+ <optional>
+ <attribute name='ephemeral'>
+ <choice>
+ <value>yes</value>
+ <value>no</value>
+ </choice>
+ </attribute>
+ </optional>
+ <optional>
+ <attribute name='private'>
+ <choice>
+ <value>yes</value>
+ <value>no</value>
+ </choice>
+ </attribute>
+ </optional>
+ <interleave>
+ <optional>
+ <element name='uuid'>
+ <text/>
+ </element>
+ </optional>
+ <optional>
+ <element name='description'>
+ <text/>
+ </element>
+ </optional>
+ <optional>
+ <element name='volume'>
+ <text/>
+ </element>
+ </optional>
+ </interleave>
+ </element>
+ </define>
+</grammar>
diff --git a/docs/sitemap.html b/docs/sitemap.html
index f79a533..901633d 100644
--- a/docs/sitemap.html
+++ b/docs/sitemap.html
@@ -141,6 +141,9 @@
</li><li>
<a href="formatnode.html">Node Devices</a>
<span>The host device XML format</span>
+ </li><li>
+ <a href="formatsecret.html">Secrets</a>
+ <span>The secret XML format</span>
</li></ul></li><li>
<a href="drivers.html">Drivers</a>
<span>Hypervisor specific driver information</span>
diff --git a/docs/sitemap.html.in b/docs/sitemap.html.in
index 9589878..2ed25c6 100644
--- a/docs/sitemap.html.in
+++ b/docs/sitemap.html.in
@@ -106,6 +106,10 @@
<a href="formatnode.html">Node Devices</a>
<span>The host device XML format</span>
</li>
+ <li>
+ <a href="formatsecret.html">Secrets</a>
+ <span>The secret XML format</span>
+ </li>
</ul>
</li>
<li>
diff --git a/include/libvirt/libvirt.h b/include/libvirt/libvirt.h
index 855f755..fd5a70f 100644
--- a/include/libvirt/libvirt.h
+++ b/include/libvirt/libvirt.h
@@ -1448,6 +1448,40 @@ void virEventRegisterImpl(virEventAddHandleFunc addHandle,
virEventAddTimeoutFunc addTimeout,
virEventUpdateTimeoutFunc updateTimeout,
virEventRemoveTimeoutFunc removeTimeout);
+
+/*
+ * Secret manipulation API
+ */
+
+/**
+ * virSecret:
+ *
+ * A virSecret stores a secret value (e.g. a passphrase or encryption key)
+ * and associated metadata.
+ */
+typedef struct _virSecret virSecret;
+typedef virSecret *virSecretPtr;
+
+virConnectPtr virSecretGetConnect (virSecretPtr secret);
+int virConnectNumOfSecrets (virConnectPtr conn);
+int virConnectListSecrets (virConnectPtr conn,
+ char **uuids,
+ int maxuuids);
+virSecretPtr virSecretLookupByUUIDString(virConnectPtr conn,
+ const char *uuid);
+virSecretPtr virSecretDefineXML (virConnectPtr conn,
+ const char *xml);
+char * virSecretGetUUIDString (virSecretPtr secret);
+char * virSecretGetXMLDesc (virSecretPtr secret);
+int virSecretSetValue (virSecretPtr secret,
+ const unsigned char *value,
+ size_t value_size);
+unsigned char * virSecretGetValue (virSecretPtr secret,
+ size_t *value_size);
+int virSecretUndefine (virSecretPtr secret);
+int virSecretRef (virSecretPtr secret);
+int virSecretFree (virSecretPtr secret);
+
#ifdef __cplusplus
}
#endif
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index e6536c7..2f7286b 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -1448,6 +1448,40 @@ void virEventRegisterImpl(virEventAddHandleFunc addHandle,
virEventAddTimeoutFunc addTimeout,
virEventUpdateTimeoutFunc updateTimeout,
virEventRemoveTimeoutFunc removeTimeout);
+
+/*
+ * Secret manipulation API
+ */
+
+/**
+ * virSecret:
+ *
+ * A virSecret stores a secret value (e.g. a passphrase or encryption key)
+ * and associated metadata.
+ */
+typedef struct _virSecret virSecret;
+typedef virSecret *virSecretPtr;
+
+virConnectPtr virSecretGetConnect (virSecretPtr secret);
+int virConnectNumOfSecrets (virConnectPtr conn);
+int virConnectListSecrets (virConnectPtr conn,
+ char **uuids,
+ int maxuuids);
+virSecretPtr virSecretLookupByUUIDString(virConnectPtr conn,
+ const char *uuid);
+virSecretPtr virSecretDefineXML (virConnectPtr conn,
+ const char *xml);
+char * virSecretGetUUIDString (virSecretPtr secret);
+char * virSecretGetXMLDesc (virSecretPtr secret);
+int virSecretSetValue (virSecretPtr secret,
+ const unsigned char *value,
+ size_t value_size);
+unsigned char * virSecretGetValue (virSecretPtr secret,
+ size_t *value_size);
+int virSecretUndefine (virSecretPtr secret);
+int virSecretRef (virSecretPtr secret);
+int virSecretFree (virSecretPtr secret);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index c06f51e..65080ed 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -292,3 +292,19 @@ LIBVIRT_0.7.0 {
} LIBVIRT_0.6.4;
# .... define new API here using predicted next version number ....
+
+LIBVIRT_0.7.1 {
+ global:
+ virSecretGetConnect;
+ virConnectNumOfSecrets;
+ virConnectListSecrets;
+ virSecretLookupByUUIDString;
+ virSecretDefineXML;
+ virSecretGetUUIDString;
+ virSecretGetXMLDesc;
+ virSecretSetValue;
+ virSecretGetValue;
+ virSecretUndefine;
+ virSecretRef;
+ virSecretFree;
+} LIBVIRT_0.7.0;
--
1.6.2.5