1
0
mirror of https://gitlab.com/libvirt/libvirt.git synced 2025-03-07 17:28:15 +00:00

storage: add auth to virDomainDiskDef

Add additional fields to let you specify the how to authenticate with a disk.
The secret to use may be referenced by a usage string or a UUID, i.e.:

<auth username='myuser'>
 <secret type='ceph' usage='secretname'/>
</auth>

or

<auth username='myuser'>
 <secret type='ceph' uuid='0a81f5b2-8403-7b23-c8d6-21ccc2f80d6f'/>
</auth>

Signed-off-by: Josh Durgin <josh.durgin@dreamhost.com>
This commit is contained in:
Josh Durgin 2011-10-28 12:29:39 -06:00 committed by Eric Blake
parent 536d1f8746
commit 5bd6271f59
7 changed files with 176 additions and 9 deletions

View File

@ -200,6 +200,7 @@ Patches have also been contributed by:
Sage Weil <sage@newdream.net> Sage Weil <sage@newdream.net>
David L Stevens <dlstevens@us.ibm.com> David L Stevens <dlstevens@us.ibm.com>
Tyler Coumbes <coumbes@gmail.com> Tyler Coumbes <coumbes@gmail.com>
Josh Durgin <josh.durgin@dreamhost.com>
[....send patches to get your name here....] [....send patches to get your name here....]

View File

@ -913,6 +913,16 @@
&lt;transient/&gt; &lt;transient/&gt;
&lt;address type='drive' controller='0' bus='1' unit='0'/&gt; &lt;address type='drive' controller='0' bus='1' unit='0'/&gt;
&lt;/disk&gt; &lt;/disk&gt;
&lt;disk type='network'&gt;
&lt;driver name="qemu" type="raw"/&gt;
&lt;source protocol="rbd" name="image_name2"&gt;
&lt;host name="hostname" port="7000"/&gt;
&lt;/source&gt;
&lt;target dev="hdd" bus="ide"/&gt;
&lt;auth username='myuser'&gt;
&lt;secret type='ceph' usage='mypassid'/&gt;
&lt;/auth&gt;
&lt;/disk&gt;
&lt;disk type='block' device='cdrom'&gt; &lt;disk type='block' device='cdrom'&gt;
&lt;driver name='qemu' type='raw'/&gt; &lt;driver name='qemu' type='raw'/&gt;
&lt;target def='hdc' bus='ide'/&gt; &lt;target def='hdc' bus='ide'/&gt;
@ -1160,7 +1170,24 @@
"drive" controller, additional attributes "drive" controller, additional attributes
<code>controller</code>, <code>bus</code>, <code>controller</code>, <code>bus</code>,
and <code>unit</code> are available, each defaulting to 0. and <code>unit</code> are available, each defaulting to 0.
</dd>
<dt><code>auth</code></dt>
<dd>If present, the <code>auth</code> element provides the
authentication credentials needed to access the source. It
includes a mandatory attribute <code>username</code>, which
identifies the username to use during authentication, as well
as a sub-element <code>secret</code> with mandatory
attribute <code>type</code>, to tie back to
a <a href="formatsecret.html">libvirt secret object</a> that
holds the actual password or other credentials (the domain XML
intentionally does not expose the password, only the reference
to the object that does manage the password). For now, the
only known secret <code>type</code> is "ceph", for Ceph RBD
network sources, and requires either an
attribute <code>uuid</code> with the UUID of the Ceph secret
object, or an attribute <code>usage</code> with the name
associated with the Ceph secret
object. <span class="since">libvirt 0.9.7</span>
</dd> </dd>
</dl> </dl>

View File

@ -602,6 +602,9 @@
<optional> <optional>
<ref name="driver"/> <ref name="driver"/>
</optional> </optional>
<optional>
<ref name="diskAuth"/>
</optional>
<ref name="target"/> <ref name="target"/>
<optional> <optional>
<ref name="deviceBoot"/> <ref name="deviceBoot"/>
@ -2535,6 +2538,32 @@
<empty/> <empty/>
</element> </element>
</define> </define>
<define name="diskAuth">
<element name="auth">
<attribute name="username">
<ref name="genericName"/>
</attribute>
<ref name="diskAuthSecret"/>
</element>
</define>
<define name='diskAuthSecret'>
<element name='secret'>
<attribute name='type'>
<choice>
<value>ceph</value>
</choice>
</attribute>
<choice>
<attribute name='uuid'>
<ref name="UUID"/>
</attribute>
<attribute name="usage">
<ref name="genericName"/>
</attribute>
</choice>
</element>
</define>
<!-- <!--
Optional hypervisor extensions in their own namespace: Optional hypervisor extensions in their own namespace:

View File

@ -1475,6 +1475,7 @@ libvirt_lxc_SOURCES = \
$(NODE_INFO_SOURCES) \ $(NODE_INFO_SOURCES) \
$(ENCRYPTION_CONF_SOURCES) \ $(ENCRYPTION_CONF_SOURCES) \
$(DOMAIN_CONF_SOURCES) \ $(DOMAIN_CONF_SOURCES) \
$(SECRET_CONF_SOURCES) \
$(CPU_CONF_SOURCES) \ $(CPU_CONF_SOURCES) \
$(NWFILTER_PARAM_CONF_SOURCES) $(NWFILTER_PARAM_CONF_SOURCES)
libvirt_lxc_LDFLAGS = $(WARN_CFLAGS) $(AM_LDFLAGS) libvirt_lxc_LDFLAGS = $(WARN_CFLAGS) $(AM_LDFLAGS)

View File

@ -49,6 +49,7 @@
#include "virfile.h" #include "virfile.h"
#include "bitmap.h" #include "bitmap.h"
#include "count-one-bits.h" #include "count-one-bits.h"
#include "secret_conf.h"
#define VIR_FROM_THIS VIR_FROM_DOMAIN #define VIR_FROM_THIS VIR_FROM_DOMAIN
@ -185,6 +186,11 @@ VIR_ENUM_IMPL(virDomainDiskProtocol, VIR_DOMAIN_DISK_PROTOCOL_LAST,
"rbd", "rbd",
"sheepdog") "sheepdog")
VIR_ENUM_IMPL(virDomainDiskSecretType, VIR_DOMAIN_DISK_SECRET_TYPE_LAST,
"none",
"uuid",
"usage")
VIR_ENUM_IMPL(virDomainDiskIo, VIR_DOMAIN_DISK_IO_LAST, VIR_ENUM_IMPL(virDomainDiskIo, VIR_DOMAIN_DISK_IO_LAST,
"default", "default",
"native", "native",
@ -788,6 +794,9 @@ void virDomainDiskDefFree(virDomainDiskDefPtr def)
VIR_FREE(def->dst); VIR_FREE(def->dst);
VIR_FREE(def->driverName); VIR_FREE(def->driverName);
VIR_FREE(def->driverType); VIR_FREE(def->driverType);
VIR_FREE(def->auth.username);
if (def->auth.secretType == VIR_DOMAIN_DISK_SECRET_TYPE_USAGE)
VIR_FREE(def->auth.secret.usage);
virStorageEncryptionFree(def->encryption); virStorageEncryptionFree(def->encryption);
virDomainDeviceInfoClear(&def->info); virDomainDeviceInfoClear(&def->info);
@ -2304,7 +2313,7 @@ virDomainDiskDefParseXML(virCapsPtr caps,
unsigned int flags) unsigned int flags)
{ {
virDomainDiskDefPtr def; virDomainDiskDefPtr def;
xmlNodePtr cur, host; xmlNodePtr cur, child;
char *type = NULL; char *type = NULL;
char *device = NULL; char *device = NULL;
char *snapshot = NULL; char *snapshot = NULL;
@ -2326,6 +2335,10 @@ virDomainDiskDefParseXML(virCapsPtr caps,
virStorageEncryptionPtr encryption = NULL; virStorageEncryptionPtr encryption = NULL;
char *serial = NULL; char *serial = NULL;
char *startupPolicy = NULL; char *startupPolicy = NULL;
char *authUsername = NULL;
char *authUsage = NULL;
char *authUUID = NULL;
char *usageType = NULL;
if (VIR_ALLOC(def) < 0) { if (VIR_ALLOC(def) < 0) {
virReportOOMError(); virReportOOMError();
@ -2382,10 +2395,10 @@ virDomainDiskDefParseXML(virCapsPtr caps,
_("missing name for disk source")); _("missing name for disk source"));
goto error; goto error;
} }
host = cur->children; child = cur->children;
while (host != NULL) { while (child != NULL) {
if (host->type == XML_ELEMENT_NODE && if (child->type == XML_ELEMENT_NODE &&
xmlStrEqual(host->name, BAD_CAST "host")) { xmlStrEqual(child->name, BAD_CAST "host")) {
if (VIR_REALLOC_N(hosts, nhosts + 1) < 0) { if (VIR_REALLOC_N(hosts, nhosts + 1) < 0) {
virReportOOMError(); virReportOOMError();
goto error; goto error;
@ -2394,20 +2407,20 @@ virDomainDiskDefParseXML(virCapsPtr caps,
hosts[nhosts].port = NULL; hosts[nhosts].port = NULL;
nhosts++; nhosts++;
hosts[nhosts - 1].name = virXMLPropString(host, "name"); hosts[nhosts - 1].name = virXMLPropString(child, "name");
if (!hosts[nhosts - 1].name) { if (!hosts[nhosts - 1].name) {
virDomainReportError(VIR_ERR_INTERNAL_ERROR, virDomainReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("missing name for host")); "%s", _("missing name for host"));
goto error; goto error;
} }
hosts[nhosts - 1].port = virXMLPropString(host, "port"); hosts[nhosts - 1].port = virXMLPropString(child, "port");
if (!hosts[nhosts - 1].port) { if (!hosts[nhosts - 1].port) {
virDomainReportError(VIR_ERR_INTERNAL_ERROR, virDomainReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("missing port for host")); "%s", _("missing port for host"));
goto error; goto error;
} }
} }
host = host->next; child = child->next;
} }
break; break;
default: default:
@ -2444,6 +2457,58 @@ virDomainDiskDefParseXML(virCapsPtr caps,
iotag = virXMLPropString(cur, "io"); iotag = virXMLPropString(cur, "io");
ioeventfd = virXMLPropString(cur, "ioeventfd"); ioeventfd = virXMLPropString(cur, "ioeventfd");
event_idx = virXMLPropString(cur, "event_idx"); event_idx = virXMLPropString(cur, "event_idx");
} else if (xmlStrEqual(cur->name, BAD_CAST "auth")) {
authUsername = virXMLPropString(cur, "username");
if (authUsername == NULL) {
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
_("missing username for auth"));
goto error;
}
def->auth.secretType = VIR_DOMAIN_DISK_SECRET_TYPE_NONE;
child = cur->children;
while (child != NULL) {
if (child->type == XML_ELEMENT_NODE &&
xmlStrEqual(child->name, BAD_CAST "secret")) {
usageType = virXMLPropString(child, "type");
if (usageType == NULL) {
virDomainReportError(VIR_ERR_XML_ERROR,
_("missing type for secret"));
goto error;
}
if (virSecretUsageTypeTypeFromString(usageType) !=
VIR_SECRET_USAGE_TYPE_CEPH) {
virDomainReportError(VIR_ERR_XML_ERROR,
_("invalid secret type %s"),
usageType);
goto error;
}
authUUID = virXMLPropString(child, "uuid");
authUsage = virXMLPropString(child, "usage");
if (authUUID != NULL && authUsage != NULL) {
virDomainReportError(VIR_ERR_XML_ERROR,
_("only one of uuid and usage can be specfied"));
goto error;
}
if (authUUID != NULL) {
def->auth.secretType = VIR_DOMAIN_DISK_SECRET_TYPE_UUID;
if (virUUIDParse(authUUID,
def->auth.secret.uuid) < 0) {
virDomainReportError(VIR_ERR_XML_ERROR,
_("malformed uuid %s"),
authUUID);
goto error;
}
} else if (authUsage != NULL) {
def->auth.secretType = VIR_DOMAIN_DISK_SECRET_TYPE_USAGE;
def->auth.secret.usage = authUsage;
authUsage = NULL;
}
}
child = child->next;
}
} else if (xmlStrEqual(cur->name, BAD_CAST "readonly")) { } else if (xmlStrEqual(cur->name, BAD_CAST "readonly")) {
def->readonly = 1; def->readonly = 1;
} else if (xmlStrEqual(cur->name, BAD_CAST "shareable")) { } else if (xmlStrEqual(cur->name, BAD_CAST "shareable")) {
@ -2683,6 +2748,8 @@ virDomainDiskDefParseXML(virCapsPtr caps,
hosts = NULL; hosts = NULL;
def->nhosts = nhosts; def->nhosts = nhosts;
nhosts = 0; nhosts = 0;
def->auth.username = authUsername;
authUsername = NULL;
def->driverName = driverName; def->driverName = driverName;
driverName = NULL; driverName = NULL;
def->driverType = driverType; def->driverType = driverType;
@ -2719,6 +2786,10 @@ cleanup:
VIR_FREE(hosts); VIR_FREE(hosts);
VIR_FREE(protocol); VIR_FREE(protocol);
VIR_FREE(device); VIR_FREE(device);
VIR_FREE(authUsername);
VIR_FREE(usageType);
VIR_FREE(authUUID);
VIR_FREE(authUsage);
VIR_FREE(driverType); VIR_FREE(driverType);
VIR_FREE(driverName); VIR_FREE(driverName);
VIR_FREE(cachetag); VIR_FREE(cachetag);
@ -9208,6 +9279,8 @@ virDomainDiskDefFormat(virBufferPtr buf,
const char *event_idx = virDomainVirtioEventIdxTypeToString(def->event_idx); const char *event_idx = virDomainVirtioEventIdxTypeToString(def->event_idx);
const char *startupPolicy = virDomainStartupPolicyTypeToString(def->startupPolicy); const char *startupPolicy = virDomainStartupPolicyTypeToString(def->startupPolicy);
char uuidstr[VIR_UUID_STRING_BUFLEN];
if (!type) { if (!type) {
virDomainReportError(VIR_ERR_INTERNAL_ERROR, virDomainReportError(VIR_ERR_INTERNAL_ERROR,
_("unexpected disk type %d"), def->type); _("unexpected disk type %d"), def->type);
@ -9265,6 +9338,23 @@ virDomainDiskDefFormat(virBufferPtr buf,
virBufferAddLit(buf, "/>\n"); virBufferAddLit(buf, "/>\n");
} }
if (def->auth.username) {
virBufferEscapeString(buf, " <auth username='%s'>\n",
def->auth.username);
if (def->auth.secretType == VIR_DOMAIN_DISK_SECRET_TYPE_UUID) {
virUUIDFormat(def->auth.secret.uuid, uuidstr);
virBufferAsprintf(buf,
" <secret type='ceph' uuid='%s'/>\n",
uuidstr);
}
if (def->auth.secretType == VIR_DOMAIN_DISK_SECRET_TYPE_USAGE) {
virBufferEscapeString(buf,
" <secret type='ceph' usage='%s'/>\n",
def->auth.secret.usage);
}
virBufferAddLit(buf, " </auth>\n");
}
if (def->src || def->nhosts > 0 || if (def->src || def->nhosts > 0 ||
def->startupPolicy) { def->startupPolicy) {
switch (def->type) { switch (def->type) {

View File

@ -278,6 +278,14 @@ enum virDomainStartupPolicy {
VIR_DOMAIN_STARTUP_POLICY_LAST VIR_DOMAIN_STARTUP_POLICY_LAST
}; };
enum virDomainDiskSecretType {
VIR_DOMAIN_DISK_SECRET_TYPE_NONE,
VIR_DOMAIN_DISK_SECRET_TYPE_UUID,
VIR_DOMAIN_DISK_SECRET_TYPE_USAGE,
VIR_DOMAIN_DISK_SECRET_TYPE_LAST
};
/* Stores the virtual disk configuration */ /* Stores the virtual disk configuration */
typedef struct _virDomainDiskDef virDomainDiskDef; typedef struct _virDomainDiskDef virDomainDiskDef;
typedef virDomainDiskDef *virDomainDiskDefPtr; typedef virDomainDiskDef *virDomainDiskDefPtr;
@ -290,6 +298,14 @@ struct _virDomainDiskDef {
int protocol; int protocol;
int nhosts; int nhosts;
virDomainDiskHostDefPtr hosts; virDomainDiskHostDefPtr hosts;
struct {
char *username;
int secretType; /* enum virDomainDiskSecretType */
union {
unsigned char uuid[VIR_UUID_BUFLEN];
char *usage;
} secret;
} auth;
char *driverName; char *driverName;
char *driverType; char *driverType;
char *serial; char *serial;
@ -1881,6 +1897,7 @@ VIR_ENUM_DECL(virDomainDiskCache)
VIR_ENUM_DECL(virDomainDiskErrorPolicy) VIR_ENUM_DECL(virDomainDiskErrorPolicy)
VIR_ENUM_DECL(virDomainDiskProtocol) VIR_ENUM_DECL(virDomainDiskProtocol)
VIR_ENUM_DECL(virDomainDiskIo) VIR_ENUM_DECL(virDomainDiskIo)
VIR_ENUM_DECL(virDomainDiskSecretType)
VIR_ENUM_DECL(virDomainDiskSnapshot) VIR_ENUM_DECL(virDomainDiskSnapshot)
VIR_ENUM_DECL(virDomainIoEventFd) VIR_ENUM_DECL(virDomainIoEventFd)
VIR_ENUM_DECL(virDomainVirtioEventIdx) VIR_ENUM_DECL(virDomainVirtioEventIdx)

View File

@ -930,6 +930,8 @@ virSecretDefFormat;
virSecretDefFree; virSecretDefFree;
virSecretDefParseFile; virSecretDefParseFile;
virSecretDefParseString; virSecretDefParseString;
virSecretUsageTypeTypeFromString;
virSecretUsageTypeTypeToString;
# security_driver.h # security_driver.h