mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-25 01:34:11 +03:00
vmx: Expose VMware Managed Object Reference (moref) in XML.
If you use the VDDK library to access virtual machines remotely, you
really need to know the Managed Object Reference ("moref") of the VM.
This must be passed each time you connect to the API.
For example nbdkit's VDDK plugin requires a moref to be passed to
mount up a VM's disk remotely:
nbdkit vddk user=root password=+/tmp/rootpw \
server=esxi.example.com thumbprint=xx:xx:xx:... \
vm=moref=2 \
file="[datastore1] Fedora/Fedora.vmdk"
Getting the moref is a huge pain. To get some idea of what it is, why
it is needed, and how much trouble it is to get it, see:
https://blogs.vmware.com/vsphere/2012/02/uniquely-identifying-virtual-machines-in-vsphere-and-vcloud-part-1-overview.html
https://blogs.vmware.com/vsphere/2012/02/uniquely-identifying-virtual-machines-in-vsphere-and-vcloud-part-2-technical.html
However the moref is available conveniently in the internals of the
libvirt VMX driver. This patch exposes it as a custom XML element
using the same "vmware:" namespace which was previously used for the
datacenterpath (see libvirt commit 636a990587
).
It appears in the XML like this:
<domain type='vmware' xmlns:vmware='http://libvirt.org/schemas/domain/vmware/1.0'>
<name>Fedora</name>
...
<vmware:datacenterpath>ha-datacenter</vmware:datacenterpath>
<vmware:moref>2</vmware:moref>
</domain>
Note that the moref can appear as either a simple ID (for esx://
connections) or as a "vm-<ID>" (for vpx:// connections). It should be
treated by users as an opaque string.
Signed-off-by: Richard W.M. Jones <rjones@redhat.com>
This commit is contained in:
parent
4ee36c33ed
commit
4c10c38275
@ -2645,6 +2645,7 @@ esxDomainGetXMLDesc(virDomainPtr domain, unsigned int flags)
|
||||
esxVI_ObjectContent *virtualMachine = NULL;
|
||||
esxVI_VirtualMachinePowerState powerState;
|
||||
int id;
|
||||
char *moref = NULL;
|
||||
char *vmPathName = NULL;
|
||||
char *datastoreName = NULL;
|
||||
char *directoryName = NULL;
|
||||
@ -2670,6 +2671,7 @@ esxDomainGetXMLDesc(virDomainPtr domain, unsigned int flags)
|
||||
esxVI_LookupVirtualMachineByUuid(priv->primary, domain->uuid,
|
||||
propertyNameList, &virtualMachine,
|
||||
esxVI_Occurrence_RequiredItem) < 0 ||
|
||||
esxVI_GetVirtualMachineMORef(virtualMachine, &moref) < 0 ||
|
||||
esxVI_GetVirtualMachinePowerState(virtualMachine, &powerState) < 0 ||
|
||||
esxVI_GetVirtualMachineIdentity(virtualMachine, &id, NULL, NULL) < 0 ||
|
||||
esxVI_GetStringValue(virtualMachine, "config.files.vmPathName",
|
||||
@ -2715,6 +2717,7 @@ esxDomainGetXMLDesc(virDomainPtr domain, unsigned int flags)
|
||||
ctx.formatFileName = NULL;
|
||||
ctx.autodetectSCSIControllerModel = NULL;
|
||||
ctx.datacenterPath = priv->primary->datacenterPath;
|
||||
ctx.moref = moref;
|
||||
|
||||
def = virVMXParseConfig(&ctx, priv->xmlopt, priv->caps, vmx);
|
||||
|
||||
@ -2732,6 +2735,7 @@ esxDomainGetXMLDesc(virDomainPtr domain, unsigned int flags)
|
||||
|
||||
esxVI_String_Free(&propertyNameList);
|
||||
esxVI_ObjectContent_Free(&virtualMachine);
|
||||
VIR_FREE(moref);
|
||||
VIR_FREE(datastoreName);
|
||||
VIR_FREE(directoryName);
|
||||
VIR_FREE(directoryAndFileName);
|
||||
@ -2774,6 +2778,7 @@ esxConnectDomainXMLFromNative(virConnectPtr conn, const char *nativeFormat,
|
||||
ctx.formatFileName = NULL;
|
||||
ctx.autodetectSCSIControllerModel = NULL;
|
||||
ctx.datacenterPath = NULL;
|
||||
ctx.moref = NULL;
|
||||
|
||||
def = virVMXParseConfig(&ctx, priv->xmlopt, priv->caps, nativeConfig);
|
||||
|
||||
@ -2830,6 +2835,7 @@ esxConnectDomainXMLToNative(virConnectPtr conn, const char *nativeFormat,
|
||||
ctx.formatFileName = esxFormatVMXFileName;
|
||||
ctx.autodetectSCSIControllerModel = esxAutodetectSCSIControllerModel;
|
||||
ctx.datacenterPath = NULL;
|
||||
ctx.moref = NULL;
|
||||
|
||||
vmx = virVMXFormatConfig(&ctx, priv->xmlopt, def, virtualHW_version);
|
||||
|
||||
@ -3077,6 +3083,7 @@ esxDomainDefineXMLFlags(virConnectPtr conn, const char *xml, unsigned int flags)
|
||||
ctx.formatFileName = esxFormatVMXFileName;
|
||||
ctx.autodetectSCSIControllerModel = esxAutodetectSCSIControllerModel;
|
||||
ctx.datacenterPath = NULL;
|
||||
ctx.moref = NULL;
|
||||
|
||||
vmx = virVMXFormatConfig(&ctx, priv->xmlopt, def, virtualHW_version);
|
||||
|
||||
|
@ -2390,6 +2390,19 @@ esxVI_GetVirtualMachineQuestionInfo
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
esxVI_GetVirtualMachineMORef(esxVI_ObjectContent *virtualMachine,
|
||||
char **moref)
|
||||
{
|
||||
for (; virtualMachine != NULL; virtualMachine = virtualMachine->_next) {
|
||||
if (virtualMachine->obj &&
|
||||
STREQ(virtualMachine->obj->type, "VirtualMachine") &&
|
||||
virtualMachine->obj->value) {
|
||||
return VIR_STRDUP(*moref, virtualMachine->obj->value);
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
esxVI_GetBoolean(esxVI_ObjectContent *objectContent, const char *propertyName,
|
||||
|
@ -334,6 +334,10 @@ int esxVI_GetVirtualMachineQuestionInfo
|
||||
(esxVI_ObjectContent *virtualMachine,
|
||||
esxVI_VirtualMachineQuestionInfo **questionInfo);
|
||||
|
||||
int esxVI_GetVirtualMachineMORef
|
||||
(esxVI_ObjectContent *virtualMachine,
|
||||
char **moref);
|
||||
|
||||
int esxVI_GetBoolean(esxVI_ObjectContent *objectContent,
|
||||
const char *propertyName,
|
||||
esxVI_Boolean *value, esxVI_Occurrence occurrence);
|
||||
|
@ -553,23 +553,41 @@ static virDomainDefParserConfig virVMXDomainDefParserConfig = {
|
||||
VIR_DOMAIN_DEF_FEATURE_NAME_SLASH),
|
||||
};
|
||||
|
||||
struct virVMXDomainDefNamespaceData {
|
||||
char *datacenterPath;
|
||||
char *moref;
|
||||
};
|
||||
|
||||
static void
|
||||
virVMXDomainDefNamespaceFree(void *nsdata)
|
||||
{
|
||||
VIR_FREE(nsdata);
|
||||
struct virVMXDomainDefNamespaceData *data = nsdata;
|
||||
|
||||
if (data) {
|
||||
VIR_FREE(data->datacenterPath);
|
||||
VIR_FREE(data->moref);
|
||||
}
|
||||
VIR_FREE(data);
|
||||
}
|
||||
|
||||
static int
|
||||
virVMXDomainDefNamespaceFormatXML(virBufferPtr buf, void *nsdata)
|
||||
{
|
||||
const char *datacenterPath = nsdata;
|
||||
struct virVMXDomainDefNamespaceData *data = nsdata;
|
||||
|
||||
if (!datacenterPath)
|
||||
if (!data)
|
||||
return 0;
|
||||
|
||||
virBufferAddLit(buf, "<vmware:datacenterpath>");
|
||||
virBufferEscapeString(buf, "%s", datacenterPath);
|
||||
virBufferAddLit(buf, "</vmware:datacenterpath>\n");
|
||||
if (data->datacenterPath) {
|
||||
virBufferAddLit(buf, "<vmware:datacenterpath>");
|
||||
virBufferEscapeString(buf, "%s", data->datacenterPath);
|
||||
virBufferAddLit(buf, "</vmware:datacenterpath>\n");
|
||||
}
|
||||
if (data->moref) {
|
||||
virBufferAddLit(buf, "<vmware:moref>");
|
||||
virBufferEscapeString(buf, "%s", data->moref);
|
||||
virBufferAddLit(buf, "</vmware:moref>\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1304,7 +1322,6 @@ virVMXParseConfig(virVMXContext *ctx,
|
||||
bool hgfs_disabled = true;
|
||||
long long sharedFolder_maxNum = 0;
|
||||
int cpumasklen;
|
||||
char *namespaceData;
|
||||
|
||||
if (ctx->parseFileName == NULL) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
@ -1802,12 +1819,18 @@ virVMXParseConfig(virVMXContext *ctx,
|
||||
}
|
||||
|
||||
/* ctx:datacenterPath -> def:namespaceData */
|
||||
if (ctx->datacenterPath) {
|
||||
if (VIR_STRDUP(namespaceData, ctx->datacenterPath) < 0)
|
||||
if (ctx->datacenterPath || ctx->moref) {
|
||||
struct virVMXDomainDefNamespaceData *nsdata = NULL;
|
||||
|
||||
if (VIR_ALLOC(nsdata) < 0 ||
|
||||
VIR_STRDUP(nsdata->datacenterPath, ctx->datacenterPath) < 0 ||
|
||||
VIR_STRDUP(nsdata->moref, ctx->moref) < 0) {
|
||||
virVMXDomainDefNamespaceFree(nsdata);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
def->ns = *virDomainXMLOptionGetNamespace(xmlopt);
|
||||
def->namespaceData = namespaceData;
|
||||
def->namespaceData = nsdata;
|
||||
}
|
||||
|
||||
if (virDomainDefPostParse(def, caps, VIR_DOMAIN_DEF_PARSE_ABI_UPDATE,
|
||||
|
@ -45,6 +45,7 @@ typedef int (*virVMXAutodetectSCSIControllerModel)(virDomainDiskDefPtr def,
|
||||
* formatFileName is only used by virVMXFormatConfig.
|
||||
* autodetectSCSIControllerModel is optionally used by virVMXFormatConfig.
|
||||
* datacenterPath is only used by virVMXFormatConfig.
|
||||
* moref is only used by virVMXFormatConfig.
|
||||
*/
|
||||
struct _virVMXContext {
|
||||
void *opaque;
|
||||
@ -52,6 +53,7 @@ struct _virVMXContext {
|
||||
virVMXFormatFileName formatFileName;
|
||||
virVMXAutodetectSCSIControllerModel autodetectSCSIControllerModel;
|
||||
const char *datacenterPath; /* including folders */
|
||||
const char *moref;
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user