提交 5bd6271f 编写于 作者: J Josh Durgin 提交者: Eric Blake

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: NJosh Durgin <josh.durgin@dreamhost.com>
上级 536d1f87
......@@ -200,6 +200,7 @@ Patches have also been contributed by:
Sage Weil <sage@newdream.net>
David L Stevens <dlstevens@us.ibm.com>
Tyler Coumbes <coumbes@gmail.com>
Josh Durgin <josh.durgin@dreamhost.com>
[....send patches to get your name here....]
......
......@@ -913,6 +913,16 @@
&lt;transient/&gt;
&lt;address type='drive' controller='0' bus='1' unit='0'/&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;driver name='qemu' type='raw'/&gt;
&lt;target def='hdc' bus='ide'/&gt;
......@@ -1160,7 +1170,24 @@
"drive" controller, additional attributes
<code>controller</code>, <code>bus</code>,
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>
</dl>
......
......@@ -602,6 +602,9 @@
<optional>
<ref name="driver"/>
</optional>
<optional>
<ref name="diskAuth"/>
</optional>
<ref name="target"/>
<optional>
<ref name="deviceBoot"/>
......@@ -2535,6 +2538,32 @@
<empty/>
</element>
</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:
......
......@@ -1475,6 +1475,7 @@ libvirt_lxc_SOURCES = \
$(NODE_INFO_SOURCES) \
$(ENCRYPTION_CONF_SOURCES) \
$(DOMAIN_CONF_SOURCES) \
$(SECRET_CONF_SOURCES) \
$(CPU_CONF_SOURCES) \
$(NWFILTER_PARAM_CONF_SOURCES)
libvirt_lxc_LDFLAGS = $(WARN_CFLAGS) $(AM_LDFLAGS)
......
......@@ -49,6 +49,7 @@
#include "virfile.h"
#include "bitmap.h"
#include "count-one-bits.h"
#include "secret_conf.h"
#define VIR_FROM_THIS VIR_FROM_DOMAIN
......@@ -185,6 +186,11 @@ VIR_ENUM_IMPL(virDomainDiskProtocol, VIR_DOMAIN_DISK_PROTOCOL_LAST,
"rbd",
"sheepdog")
VIR_ENUM_IMPL(virDomainDiskSecretType, VIR_DOMAIN_DISK_SECRET_TYPE_LAST,
"none",
"uuid",
"usage")
VIR_ENUM_IMPL(virDomainDiskIo, VIR_DOMAIN_DISK_IO_LAST,
"default",
"native",
......@@ -788,6 +794,9 @@ void virDomainDiskDefFree(virDomainDiskDefPtr def)
VIR_FREE(def->dst);
VIR_FREE(def->driverName);
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);
virDomainDeviceInfoClear(&def->info);
......@@ -2304,7 +2313,7 @@ virDomainDiskDefParseXML(virCapsPtr caps,
unsigned int flags)
{
virDomainDiskDefPtr def;
xmlNodePtr cur, host;
xmlNodePtr cur, child;
char *type = NULL;
char *device = NULL;
char *snapshot = NULL;
......@@ -2326,6 +2335,10 @@ virDomainDiskDefParseXML(virCapsPtr caps,
virStorageEncryptionPtr encryption = NULL;
char *serial = NULL;
char *startupPolicy = NULL;
char *authUsername = NULL;
char *authUsage = NULL;
char *authUUID = NULL;
char *usageType = NULL;
if (VIR_ALLOC(def) < 0) {
virReportOOMError();
......@@ -2382,10 +2395,10 @@ virDomainDiskDefParseXML(virCapsPtr caps,
_("missing name for disk source"));
goto error;
}
host = cur->children;
while (host != NULL) {
if (host->type == XML_ELEMENT_NODE &&
xmlStrEqual(host->name, BAD_CAST "host")) {
child = cur->children;
while (child != NULL) {
if (child->type == XML_ELEMENT_NODE &&
xmlStrEqual(child->name, BAD_CAST "host")) {
if (VIR_REALLOC_N(hosts, nhosts + 1) < 0) {
virReportOOMError();
goto error;
......@@ -2394,20 +2407,20 @@ virDomainDiskDefParseXML(virCapsPtr caps,
hosts[nhosts].port = NULL;
nhosts++;
hosts[nhosts - 1].name = virXMLPropString(host, "name");
hosts[nhosts - 1].name = virXMLPropString(child, "name");
if (!hosts[nhosts - 1].name) {
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("missing name for host"));
goto error;
}
hosts[nhosts - 1].port = virXMLPropString(host, "port");
hosts[nhosts - 1].port = virXMLPropString(child, "port");
if (!hosts[nhosts - 1].port) {
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("missing port for host"));
goto error;
}
}
host = host->next;
child = child->next;
}
break;
default:
......@@ -2444,6 +2457,58 @@ virDomainDiskDefParseXML(virCapsPtr caps,
iotag = virXMLPropString(cur, "io");
ioeventfd = virXMLPropString(cur, "ioeventfd");
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")) {
def->readonly = 1;
} else if (xmlStrEqual(cur->name, BAD_CAST "shareable")) {
......@@ -2683,6 +2748,8 @@ virDomainDiskDefParseXML(virCapsPtr caps,
hosts = NULL;
def->nhosts = nhosts;
nhosts = 0;
def->auth.username = authUsername;
authUsername = NULL;
def->driverName = driverName;
driverName = NULL;
def->driverType = driverType;
......@@ -2719,6 +2786,10 @@ cleanup:
VIR_FREE(hosts);
VIR_FREE(protocol);
VIR_FREE(device);
VIR_FREE(authUsername);
VIR_FREE(usageType);
VIR_FREE(authUUID);
VIR_FREE(authUsage);
VIR_FREE(driverType);
VIR_FREE(driverName);
VIR_FREE(cachetag);
......@@ -9208,6 +9279,8 @@ virDomainDiskDefFormat(virBufferPtr buf,
const char *event_idx = virDomainVirtioEventIdxTypeToString(def->event_idx);
const char *startupPolicy = virDomainStartupPolicyTypeToString(def->startupPolicy);
char uuidstr[VIR_UUID_STRING_BUFLEN];
if (!type) {
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
_("unexpected disk type %d"), def->type);
......@@ -9265,6 +9338,23 @@ virDomainDiskDefFormat(virBufferPtr buf,
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 ||
def->startupPolicy) {
switch (def->type) {
......
......@@ -278,6 +278,14 @@ enum virDomainStartupPolicy {
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 */
typedef struct _virDomainDiskDef virDomainDiskDef;
typedef virDomainDiskDef *virDomainDiskDefPtr;
......@@ -290,6 +298,14 @@ struct _virDomainDiskDef {
int protocol;
int nhosts;
virDomainDiskHostDefPtr hosts;
struct {
char *username;
int secretType; /* enum virDomainDiskSecretType */
union {
unsigned char uuid[VIR_UUID_BUFLEN];
char *usage;
} secret;
} auth;
char *driverName;
char *driverType;
char *serial;
......@@ -1881,6 +1897,7 @@ VIR_ENUM_DECL(virDomainDiskCache)
VIR_ENUM_DECL(virDomainDiskErrorPolicy)
VIR_ENUM_DECL(virDomainDiskProtocol)
VIR_ENUM_DECL(virDomainDiskIo)
VIR_ENUM_DECL(virDomainDiskSecretType)
VIR_ENUM_DECL(virDomainDiskSnapshot)
VIR_ENUM_DECL(virDomainIoEventFd)
VIR_ENUM_DECL(virDomainVirtioEventIdx)
......
......@@ -930,6 +930,8 @@ virSecretDefFormat;
virSecretDefFree;
virSecretDefParseFile;
virSecretDefParseString;
virSecretUsageTypeTypeFromString;
virSecretUsageTypeTypeToString;
# security_driver.h
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册