[libvirt] [PATCH] esx: Add vpx:// scheme to allow direct connection to a vCenter

Add a pointer to the primary context of a connection and use it in all driver functions that don't dependent on the context type. This includes almost all functions that deal with a virDomianPtr. Therefore, using a vpx:// connection allows you to perform all the usual domain related actions like start, destroy, suspend, resume, dumpxml etc. Some functions that require an explicitly specified ESX server don't work yet. This includes the host UUID, the hostname, the general node info, the max vCPU count and the free memory. Also not working yet are migration and defining new domains. --- docs/drvesx.html.in | 21 +- src/esx/esx_driver.c | 931 ++++++++++++++++++++++++------------------ src/esx/esx_private.h | 1 + src/esx/esx_storage_driver.c | 33 +- src/esx/esx_vmx.c | 2 + src/libvirt.c | 1 + 6 files changed, 562 insertions(+), 427 deletions(-) diff --git a/docs/drvesx.html.in b/docs/drvesx.html.in index e8cee77..1f2ae4e 100644 --- a/docs/drvesx.html.in +++ b/docs/drvesx.html.in @@ -4,13 +4,14 @@ <p> The libvirt VMware ESX driver can manage VMware ESX/ESXi 3.5/4.0 and VMware GSX 2.0, also called VMware Server 2.0, and possibly later - versions. + versions. <span class="since">Since 0.8.3</span> the driver can also + connect to a VMware vCenter 2.5/4.0 (VPX). </p> <h2><a name="prereq">Deployment pre-requisites</a></h2> <p> - None. Any out-of-the-box installation of ESX/GSX should work. No + None. Any out-of-the-box installation of VPX/ESX(i)/GSX should work. No preparations are required on the server side, no libvirtd must be installed on the ESX server. The driver uses version 2.5 of the remote, SOAP based @@ -27,10 +28,11 @@ Some example remote connection URIs for the driver are: </p> <pre> -esx://example.com (ESX over HTTPS) -gsx://example.com (GSX over HTTPS) -esx://example.com/?transport=http (ESX over HTTP) -esx://example.com/?no_verify=1 (ESX over HTTPS, but doesn't verify the server's SSL certificate) +vpx://example-vcenter.com (VPX over HTTPS) +esx://example-esx.com (ESX over HTTPS) +gsx://example-gsx.com (GSX over HTTPS) +esx://example-esx.com/?transport=http (ESX over HTTP) +esx://example-esx.com/?no_verify=1 (ESX over HTTPS, but doesn't verify the server's SSL certificate) </pre> <p> <strong>Note</strong>: In contrast to other drivers, the ESX driver is @@ -49,9 +51,9 @@ esx://example.com/?no_verify=1 (ESX over HTTPS, but doesn't verify the serve type://[username@]hostname[:port]/[?extraparameters] </pre> <p> - The <code>type://</code> is either <code>esx://</code> or + The <code>type://</code> is either <code>vpx://</code> or <code>esx://</code> or <code>gsx://</code> and the driver selects the default port depending - on it. For ESX the default HTTPS port is 443, for GSX it is 8333. If + on it. For VPX and ESX the default HTTPS port is 443, for GSX it is 8333. If the port parameter is given, it overrides the default port. </p> @@ -76,7 +78,7 @@ type://[username@]hostname[:port]/[?extraparameters] <code>http</code> or <code>https</code> </td> <td> - Overrides the default HTTPS transport. For ESX the default + Overrides the default HTTPS transport. For VPX and ESX the default HTTP port is 80, for GSX it is 8222. </td> </tr> @@ -91,6 +93,7 @@ type://[username@]hostname[:port]/[?extraparameters] In order to perform a migration the driver needs to know the VMware vCenter for the ESX server. If set to <code>*</code>, the driver connects to the vCenter known to the ESX server. + This paramater in useful when connecting to an ESX server only. </td> </tr> <tr> diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c index 33f421d..5922cb6 100644 --- a/src/esx/esx_driver.c +++ b/src/esx/esx_driver.c @@ -67,6 +67,11 @@ esxSupportsLongMode(esxPrivate *priv) return priv->supportsLongMode; } + if (priv->host == NULL) { + /* FIXME: Currently no host for a vpx:// connection */ + return esxVI_Boolean_False; + } + if (esxVI_EnsureSession(priv->host) < 0) { return esxVI_Boolean_Undefined; } @@ -148,6 +153,11 @@ esxLookupHostSystemBiosUuid(esxPrivate *priv, unsigned char *uuid) esxVI_ObjectContent *hostSystem = NULL; esxVI_DynamicProperty *dynamicProperty = NULL; + if (priv->host == NULL) { + /* FIXME: Currently no host for a vpx:// connection */ + return 0; + } + if (esxVI_EnsureSession(priv->host) < 0) { return -1; } @@ -280,11 +290,204 @@ esxCapsInit(esxPrivate *priv) +static int +esxConnectToHost(esxPrivate *priv, virConnectAuthPtr auth, + const char *hostname, int port, + const char *predefinedUsername, + esxUtil_ParsedQuery *parsedQuery, + esxVI_ProductVersion expectedProductVersion, + char **vCenterIpAddress) +{ + int result = -1; + char ipAddress[NI_MAXHOST] = ""; + char *username = NULL; + char *password = NULL; + char *url = NULL; + esxVI_String *propertyNameList = NULL; + esxVI_ObjectContent *hostSystem = NULL; + esxVI_Boolean inMaintenanceMode = esxVI_Boolean_Undefined; + + if (vCenterIpAddress == NULL || *vCenterIpAddress != NULL) { + ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument")); + return -1; + } + + if (esxUtil_ResolveHostname(hostname, ipAddress, NI_MAXHOST) < 0) { + return -1; + } + + if (predefinedUsername != NULL) { + username = strdup(predefinedUsername); + + if (username == NULL) { + virReportOOMError(); + goto cleanup; + } + } else { + username = virRequestUsername(auth, "root", hostname); + + if (username == NULL) { + ESX_ERROR(VIR_ERR_AUTH_FAILED, "%s", _("Username request failed")); + goto cleanup; + } + } + + password = virRequestPassword(auth, username, hostname); + + if (password == NULL) { + ESX_ERROR(VIR_ERR_AUTH_FAILED, "%s", _("Password request failed")); + goto cleanup; + } + + if (virAsprintf(&url, "%s://%s:%d/sdk", priv->transport, hostname, + port) < 0) { + virReportOOMError(); + goto cleanup; + } + + if (esxVI_Context_Alloc(&priv->host) < 0 || + esxVI_Context_Connect(priv->host, url, ipAddress, username, password, + parsedQuery) < 0) { + goto cleanup; + } + + if (expectedProductVersion == esxVI_ProductVersion_ESX) { + if (priv->host->productVersion != esxVI_ProductVersion_ESX35 && + priv->host->productVersion != esxVI_ProductVersion_ESX40) { + ESX_ERROR(VIR_ERR_INTERNAL_ERROR, + _("%s is neither an ESX 3.5 host nor an ESX 4.0 host"), + hostname); + goto cleanup; + } + } else { /* GSX */ + if (priv->host->productVersion != esxVI_ProductVersion_GSX20) { + ESX_ERROR(VIR_ERR_INTERNAL_ERROR, + _("%s isn't a GSX 2.0 host"), hostname); + goto cleanup; + } + } + + /* Query the host for maintenance mode and vCenter IP address */ + if (esxVI_String_AppendValueListToList(&propertyNameList, + "runtime.inMaintenanceMode\0" + "summary.managementServerIp\0") < 0 || + esxVI_LookupHostSystemByIp(priv->host, ipAddress, propertyNameList, + &hostSystem) < 0 || + esxVI_GetBoolean(hostSystem, "runtime.inMaintenanceMode", + &inMaintenanceMode, + esxVI_Occurrence_RequiredItem) < 0 || + esxVI_GetStringValue(hostSystem, "summary.managementServerIp", + vCenterIpAddress, + esxVI_Occurrence_OptionalItem) < 0) { + goto cleanup; + } + + /* Warn if host is in maintenance mode */ + if (inMaintenanceMode == esxVI_Boolean_True) { + VIR_WARN0("The server is in maintenance mode"); + } + + if (*vCenterIpAddress != NULL) { + *vCenterIpAddress = strdup(*vCenterIpAddress); + + if (*vCenterIpAddress == NULL) { + virReportOOMError(); + goto cleanup; + } + } + + result = 0; + + cleanup: + VIR_FREE(password); + VIR_FREE(username); + VIR_FREE(url); + esxVI_String_Free(&propertyNameList); + esxVI_ObjectContent_Free(&hostSystem); + + return result; +} + + + +static int +esxConnectToVCenter(esxPrivate *priv, virConnectAuthPtr auth, + const char *hostname, int port, + const char *predefinedUsername, + esxUtil_ParsedQuery *parsedQuery) +{ + int result = -1; + char ipAddress[NI_MAXHOST] = ""; + char *username = NULL; + char *password = NULL; + char *url = NULL; + + if (esxUtil_ResolveHostname(hostname, ipAddress, NI_MAXHOST) < 0) { + return -1; + } + + if (predefinedUsername != NULL) { + username = strdup(predefinedUsername); + + if (username == NULL) { + virReportOOMError(); + goto cleanup; + } + } else { + username = virRequestUsername(auth, "administrator", hostname); + + if (username == NULL) { + ESX_ERROR(VIR_ERR_AUTH_FAILED, "%s", _("Username request failed")); + goto cleanup; + } + } + + password = virRequestPassword(auth, username, hostname); + + if (password == NULL) { + ESX_ERROR(VIR_ERR_AUTH_FAILED, "%s", _("Password request failed")); + goto cleanup; + } + + if (virAsprintf(&url, "%s://%s:%d/sdk", priv->transport, hostname, + port) < 0) { + virReportOOMError(); + goto cleanup; + } + + if (esxVI_Context_Alloc(&priv->vCenter) < 0 || + esxVI_Context_Connect(priv->vCenter, url, ipAddress, username, + password, parsedQuery) < 0) { + goto cleanup; + } + + if (priv->vCenter->productVersion != esxVI_ProductVersion_VPX25 && + priv->vCenter->productVersion != esxVI_ProductVersion_VPX40) { + ESX_ERROR(VIR_ERR_INTERNAL_ERROR, + _("%s is neither a vCenter 2.5 server nor a vCenter " + "4.0 server"), hostname); + goto cleanup; + } + + result = 0; + + cleanup: + VIR_FREE(password); + VIR_FREE(username); + VIR_FREE(url); + + return result; +} + + + /* - * URI format: {esx|gsx}://[<username>@]<hostname>[:<port>]/[<query parameter> ...] + * URI format: {vpx|esx|gsx}://[<username>@]<hostname>[:<port>]/[<query parameter> ...] * * If no port is specified the default port is set dependent on the scheme and * transport parameter: + * - vpx+http 80 + * - vpx+https 443 * - esx+http 80 * - esx+https 443 * - gsx+http 8222 @@ -292,7 +495,7 @@ esxCapsInit(esxPrivate *priv) * * Optional query parameters: * - transport={http|https} - * - vcenter={<vcenter>|*} + * - vcenter={<vcenter>|*} only useful for an esx:// connection * - no_verify={0|1} * - auto_answer={0|1} * - proxy=[{http|socks|socks4|socks4a|socks5}://]<hostname>[:<port>] @@ -322,19 +525,13 @@ esxOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED) virDrvOpenStatus result = VIR_DRV_OPEN_ERROR; esxPrivate *priv = NULL; esxUtil_ParsedQuery *parsedQuery = NULL; - char hostIpAddress[NI_MAXHOST] = ""; + char *potentialVCenterIpAddress = NULL; char vCenterIpAddress[NI_MAXHOST] = ""; - char *url = NULL; - char *vCenter = NULL; - char *username = NULL; - char *password = NULL; - esxVI_String *propertyNameList = NULL; - esxVI_ObjectContent *hostSystem = NULL; - esxVI_DynamicProperty *dynamicProperty = NULL; - /* Decline if the URI is NULL or the scheme is neither 'esx' nor 'gsx' */ + /* Decline if the URI is NULL or the scheme is not one of {vpx|esx|gsx} */ if (conn->uri == NULL || conn->uri->scheme == NULL || - (STRCASENEQ(conn->uri->scheme, "esx") && + (STRCASENEQ(conn->uri->scheme, "vpx") && + STRCASENEQ(conn->uri->scheme, "esx") && STRCASENEQ(conn->uri->scheme, "gsx"))) { return VIR_DRV_OPEN_DECLINED; } @@ -376,7 +573,8 @@ esxOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED) * distinguish between the situations port == 0 and port != 0 */ if (conn->uri->port == 0) { - if (STRCASEEQ(conn->uri->scheme, "esx")) { + if (STRCASEEQ(conn->uri->scheme, "vpx") || + STRCASEEQ(conn->uri->scheme, "esx")) { if (STRCASEEQ(priv->transport, "https")) { conn->uri->port = 443; } else { @@ -391,194 +589,67 @@ esxOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED) } } - /* Login to host */ - if (esxUtil_ResolveHostname(conn->uri->server, hostIpAddress, - NI_MAXHOST) < 0) { - goto cleanup; - } - - if (virAsprintf(&url, "%s://%s:%d/sdk", priv->transport, - conn->uri->server, conn->uri->port) < 0) { - virReportOOMError(); - goto cleanup; - } - - if (conn->uri->user != NULL) { - username = strdup(conn->uri->user); - - if (username == NULL) { - virReportOOMError(); - goto cleanup; - } - } else { - username = virRequestUsername(auth, "root", conn->uri->server); - - if (username == NULL) { - ESX_ERROR(VIR_ERR_AUTH_FAILED, "%s", _("Username request failed")); - goto cleanup; - } - } - - password = virRequestPassword(auth, username, conn->uri->server); - - if (password == NULL) { - ESX_ERROR(VIR_ERR_AUTH_FAILED, "%s", _("Password request failed")); - goto cleanup; - } - - if (esxVI_Context_Alloc(&priv->host) < 0 || - esxVI_Context_Connect(priv->host, url, hostIpAddress, username, - password, parsedQuery) < 0) { - goto cleanup; - } - - if (STRCASEEQ(conn->uri->scheme, "esx")) { - if (priv->host->productVersion != esxVI_ProductVersion_ESX35 && - priv->host->productVersion != esxVI_ProductVersion_ESX40) { - ESX_ERROR(VIR_ERR_INTERNAL_ERROR, - _("%s is neither an ESX 3.5 host nor an ESX 4.0 host"), - conn->uri->server); + if (STRCASEEQ(conn->uri->scheme, "esx") || + STRCASEEQ(conn->uri->scheme, "gsx")) { + /* Connect to host */ + if (esxConnectToHost(priv, auth, conn->uri->server, conn->uri->port, + conn->uri->user, parsedQuery, + STRCASEEQ(conn->uri->scheme, "esx") + ? esxVI_ProductVersion_ESX + : esxVI_ProductVersion_GSX, + &potentialVCenterIpAddress) < 0) { goto cleanup; } - } else { /* GSX */ - if (priv->host->productVersion != esxVI_ProductVersion_GSX20) { - ESX_ERROR(VIR_ERR_INTERNAL_ERROR, - _("%s isn't a GSX 2.0 host"), conn->uri->server); - goto cleanup; - } - } - - /* Query the host for maintenance mode and vCenter IP address */ - if (esxVI_String_AppendValueListToList(&propertyNameList, - "runtime.inMaintenanceMode\0" - "summary.managementServerIp\0") < 0 || - esxVI_LookupHostSystemByIp(priv->host, hostIpAddress, propertyNameList, - &hostSystem) < 0) { - goto cleanup; - } - /* Warn if host is in maintenance mode */ - for (dynamicProperty = hostSystem->propSet; dynamicProperty != NULL; - dynamicProperty = dynamicProperty->_next) { - if (STREQ(dynamicProperty->name, "runtime.inMaintenanceMode")) { - if (esxVI_AnyType_ExpectType(dynamicProperty->val, - esxVI_Type_Boolean) < 0) { - goto cleanup; - } - - if (dynamicProperty->val->boolean == esxVI_Boolean_True) { - VIR_WARN0("The server is in maintenance mode"); - } - - break; - } - } - - /* Login to vCenter */ - if (parsedQuery->vCenter != NULL) { - VIR_FREE(url); - VIR_FREE(password); - VIR_FREE(username); - - vCenter = strdup(parsedQuery->vCenter); - - if (vCenter == NULL) { - virReportOOMError(); - goto cleanup; - } - - /* If a vCenter is specified resolve the hostname */ - if (STRNEQ(vCenter, "*") && - esxUtil_ResolveHostname(vCenter, vCenterIpAddress, - NI_MAXHOST) < 0) { - goto cleanup; - } - - /* Lookup the vCenter from the ESX host */ - for (dynamicProperty = hostSystem->propSet; dynamicProperty != NULL; - dynamicProperty = dynamicProperty->_next) { - if (STREQ(dynamicProperty->name, "summary.managementServerIp")) { - if (esxVI_AnyType_ExpectType(dynamicProperty->val, - esxVI_Type_String) < 0) { + /* Connect to vCenter */ + if (parsedQuery->vCenter != NULL) { + if (STREQ(parsedQuery->vCenter, "*")) { + if (potentialVCenterIpAddress == NULL) { + ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", + _("This host is not managed by a vCenter")); goto cleanup; } - /* Get the vCenter IP address or verify the specified one */ - if (STREQ(vCenter, "*")) { - VIR_FREE(vCenter); - - vCenter = strdup(dynamicProperty->val->string); - - if (vCenter == NULL) { - virReportOOMError(); - goto cleanup; - } + if (virStrcpyStatic(vCenterIpAddress, + potentialVCenterIpAddress) == NULL) { + ESX_ERROR(VIR_ERR_INTERNAL_ERROR, + _("vCenter IP address %s too big for destination"), + potentialVCenterIpAddress); + goto cleanup; + } + } else { + if (esxUtil_ResolveHostname(parsedQuery->vCenter, + vCenterIpAddress, NI_MAXHOST) < 0) { + goto cleanup; + } - if (virStrcpyStatic(vCenterIpAddress, - dynamicProperty->val->string) == NULL) { - ESX_ERROR(VIR_ERR_INTERNAL_ERROR, - _("vCenter IP address %s too big for " - "destination"), - dynamicProperty->val->string); - goto cleanup; - } - } else if (STRNEQ(vCenterIpAddress, - dynamicProperty->val->string)) { + if (potentialVCenterIpAddress != NULL && + STRNEQ(vCenterIpAddress, potentialVCenterIpAddress)) { ESX_ERROR(VIR_ERR_INTERNAL_ERROR, _("This host is managed by a vCenter with IP " "address %s, but a mismachting vCenter '%s' " "(%s) has been specified"), - dynamicProperty->val->string, vCenter, + potentialVCenterIpAddress, parsedQuery->vCenter, vCenterIpAddress); goto cleanup; } - - break; } - } - - if (STREQ(vCenter, "*")) { - ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", - _("This host is not managed by a vCenter")); - goto cleanup; - } - - if (virAsprintf(&url, "%s://%s/sdk", priv->transport, - vCenter) < 0) { - virReportOOMError(); - goto cleanup; - } - - if (esxVI_Context_Alloc(&priv->vCenter) < 0) { - goto cleanup; - } - username = virRequestUsername(auth, "administrator", vCenter); - - if (username == NULL) { - ESX_ERROR(VIR_ERR_AUTH_FAILED, "%s", _("Username request failed")); - goto cleanup; - } - - password = virRequestPassword(auth, username, vCenter); - - if (password == NULL) { - ESX_ERROR(VIR_ERR_AUTH_FAILED, "%s", _("Password request failed")); - goto cleanup; + if (esxConnectToVCenter(priv, auth, vCenterIpAddress, + conn->uri->port, NULL, parsedQuery) < 0) { + goto cleanup; + } } - if (esxVI_Context_Connect(priv->vCenter, url, vCenterIpAddress, - username, password, parsedQuery) < 0) { + priv->primary = priv->host; + } else { /* VPX */ + /* Connect to vCenter */ + if (esxConnectToVCenter(priv, auth, conn->uri->server, conn->uri->port, + conn->uri->user, parsedQuery) < 0) { goto cleanup; } - if (priv->vCenter->productVersion != esxVI_ProductVersion_VPX25 && - priv->vCenter->productVersion != esxVI_ProductVersion_VPX40) { - ESX_ERROR(VIR_ERR_INTERNAL_ERROR, - _("%s is neither a vCenter 2.5 server nor a vCenter " - "4.0 server"), conn->uri->server); - goto cleanup; - } + priv->primary = priv->vCenter; } conn->privateData = priv; @@ -604,12 +675,7 @@ esxOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED) } esxUtil_FreeParsedQuery(&parsedQuery); - VIR_FREE(url); - VIR_FREE(vCenter); - VIR_FREE(password); - VIR_FREE(username); - esxVI_String_Free(&propertyNameList); - esxVI_ObjectContent_Free(&hostSystem); + VIR_FREE(potentialVCenterIpAddress); return result; } @@ -622,12 +688,14 @@ esxClose(virConnectPtr conn) esxPrivate *priv = conn->privateData; int result = 0; - if (esxVI_EnsureSession(priv->host) < 0 || - esxVI_Logout(priv->host) < 0) { - result = -1; - } + if (priv->host != NULL) { + if (esxVI_EnsureSession(priv->host) < 0 || + esxVI_Logout(priv->host) < 0) { + result = -1; + } - esxVI_Context_Free(&priv->host); + esxVI_Context_Free(&priv->host); + } if (priv->vCenter != NULL) { if (esxVI_EnsureSession(priv->vCenter) < 0 || @@ -661,6 +729,11 @@ esxSupportsVMotion(esxPrivate *priv) return priv->supportsVMotion; } + if (priv->host == NULL) { + /* FIXME: Currently no host for a vpx:// connection */ + return esxVI_Boolean_False; + } + if (esxVI_EnsureSession(priv->host) < 0) { return esxVI_Boolean_Undefined; } @@ -745,11 +818,11 @@ esxGetVersion(virConnectPtr conn, unsigned long *version) { esxPrivate *priv = conn->privateData; - if (virParseVersionString(priv->host->service->about->version, + if (virParseVersionString(priv->primary->service->about->version, version) < 0) { ESX_ERROR(VIR_ERR_INTERNAL_ERROR, _("Could not parse version number from '%s'"), - priv->host->service->about->version); + priv->primary->service->about->version); return -1; } @@ -770,6 +843,13 @@ esxGetHostname(virConnectPtr conn) const char *domainName = NULL; char *complete = NULL; + if (priv->host == NULL) { + /* FIXME: Currently no host for a vpx:// connection */ + ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", + _("Could not retrieve the hostname for a vpx:// connection")); + return NULL; + } + if (esxVI_EnsureSession(priv->host) < 0) { return NULL; } @@ -865,6 +945,13 @@ esxNodeGetInfo(virConnectPtr conn, virNodeInfoPtr nodeinfo) memset(nodeinfo, 0, sizeof (*nodeinfo)); + if (priv->host == NULL) { + /* FIXME: Currently no host for a vpx:// connection */ + ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", + _("Nodeinfo is not available for a vpx:// connection")); + return -1; + } + if (esxVI_EnsureSession(priv->host) < 0) { return -1; } @@ -1034,13 +1121,13 @@ esxListDomains(virConnectPtr conn, int *ids, int maxids) return 0; } - if (esxVI_EnsureSession(priv->host) < 0) { + if (esxVI_EnsureSession(priv->primary) < 0) { return -1; } if (esxVI_String_AppendValueToList(&propertyNameList, "runtime.powerState") < 0 || - esxVI_LookupObjectContentByType(priv->host, priv->host->vmFolder, + esxVI_LookupObjectContentByType(priv->primary, priv->primary->vmFolder, "VirtualMachine", propertyNameList, esxVI_Boolean_True, &virtualMachineList) < 0) { @@ -1090,12 +1177,12 @@ esxNumberOfDomains(virConnectPtr conn) { esxPrivate *priv = conn->privateData; - if (esxVI_EnsureSession(priv->host) < 0) { + if (esxVI_EnsureSession(priv->primary) < 0) { return -1; } return esxVI_LookupNumberOfDomainsByPowerState - (priv->host, esxVI_VirtualMachinePowerState_PoweredOn, + (priv->primary, esxVI_VirtualMachinePowerState_PoweredOn, esxVI_Boolean_False); } @@ -1114,7 +1201,7 @@ esxDomainLookupByID(virConnectPtr conn, int id) unsigned char uuid_candidate[VIR_UUID_BUFLEN]; virDomainPtr domain = NULL; - if (esxVI_EnsureSession(priv->host) < 0) { + if (esxVI_EnsureSession(priv->primary) < 0) { return NULL; } @@ -1123,7 +1210,7 @@ esxDomainLookupByID(virConnectPtr conn, int id) "name\0" "runtime.powerState\0" "config.uuid\0") < 0 || - esxVI_LookupObjectContentByType(priv->host, priv->host->vmFolder, + esxVI_LookupObjectContentByType(priv->primary, priv->primary->vmFolder, "VirtualMachine", propertyNameList, esxVI_Boolean_True, &virtualMachineList) < 0) { @@ -1190,14 +1277,14 @@ esxDomainLookupByUUID(virConnectPtr conn, const unsigned char *uuid) char *name = NULL; virDomainPtr domain = NULL; - if (esxVI_EnsureSession(priv->host) < 0) { + if (esxVI_EnsureSession(priv->primary) < 0) { return NULL; } if (esxVI_String_AppendValueListToList(&propertyNameList, "name\0" "runtime.powerState\0") < 0 || - esxVI_LookupVirtualMachineByUuid(priv->host, uuid, propertyNameList, + esxVI_LookupVirtualMachineByUuid(priv->primary, uuid, propertyNameList, &virtualMachine, esxVI_Occurrence_RequiredItem) < 0 || esxVI_GetVirtualMachineIdentity(virtualMachine, &id, &name, NULL) < 0 || @@ -1239,7 +1326,7 @@ esxDomainLookupByName(virConnectPtr conn, const char *name) unsigned char uuid[VIR_UUID_BUFLEN]; virDomainPtr domain = NULL; - if (esxVI_EnsureSession(priv->host) < 0) { + if (esxVI_EnsureSession(priv->primary) < 0) { return NULL; } @@ -1247,7 +1334,7 @@ esxDomainLookupByName(virConnectPtr conn, const char *name) "configStatus\0" "runtime.powerState\0" "config.uuid\0") < 0 || - esxVI_LookupVirtualMachineByName(priv->host, name, propertyNameList, + esxVI_LookupVirtualMachineByName(priv->primary, name, propertyNameList, &virtualMachine, esxVI_Occurrence_OptionalItem) < 0) { goto cleanup; @@ -1297,14 +1384,14 @@ esxDomainSuspend(virDomainPtr domain) esxVI_ManagedObjectReference *task = NULL; esxVI_TaskInfoState taskInfoState; - if (esxVI_EnsureSession(priv->host) < 0) { + if (esxVI_EnsureSession(priv->primary) < 0) { return -1; } if (esxVI_String_AppendValueToList(&propertyNameList, "runtime.powerState") < 0 || esxVI_LookupVirtualMachineByUuidAndPrepareForTask - (priv->host, domain->uuid, propertyNameList, &virtualMachine, + (priv->primary, domain->uuid, propertyNameList, &virtualMachine, priv->autoAnswer) < 0 || esxVI_GetVirtualMachinePowerState(virtualMachine, &powerState) < 0) { goto cleanup; @@ -1316,8 +1403,8 @@ esxDomainSuspend(virDomainPtr domain) goto cleanup; } - if (esxVI_SuspendVM_Task(priv->host, virtualMachine->obj, &task) < 0 || - esxVI_WaitForTaskCompletion(priv->host, task, domain->uuid, + if (esxVI_SuspendVM_Task(priv->primary, virtualMachine->obj, &task) < 0 || + esxVI_WaitForTaskCompletion(priv->primary, task, domain->uuid, priv->autoAnswer, &taskInfoState) < 0) { goto cleanup; } @@ -1350,14 +1437,14 @@ esxDomainResume(virDomainPtr domain) esxVI_ManagedObjectReference *task = NULL; esxVI_TaskInfoState taskInfoState; - if (esxVI_EnsureSession(priv->host) < 0) { + if (esxVI_EnsureSession(priv->primary) < 0) { return -1; } if (esxVI_String_AppendValueToList(&propertyNameList, "runtime.powerState") < 0 || esxVI_LookupVirtualMachineByUuidAndPrepareForTask - (priv->host, domain->uuid, propertyNameList, &virtualMachine, + (priv->primary, domain->uuid, propertyNameList, &virtualMachine, priv->autoAnswer) < 0 || esxVI_GetVirtualMachinePowerState(virtualMachine, &powerState) < 0) { goto cleanup; @@ -1368,9 +1455,9 @@ esxDomainResume(virDomainPtr domain) goto cleanup; } - if (esxVI_PowerOnVM_Task(priv->host, virtualMachine->obj, NULL, + if (esxVI_PowerOnVM_Task(priv->primary, virtualMachine->obj, NULL, &task) < 0 || - esxVI_WaitForTaskCompletion(priv->host, task, domain->uuid, + esxVI_WaitForTaskCompletion(priv->primary, task, domain->uuid, priv->autoAnswer, &taskInfoState) < 0) { goto cleanup; } @@ -1401,13 +1488,13 @@ esxDomainShutdown(virDomainPtr domain) esxVI_String *propertyNameList = NULL; esxVI_VirtualMachinePowerState powerState; - if (esxVI_EnsureSession(priv->host) < 0) { + if (esxVI_EnsureSession(priv->primary) < 0) { return -1; } if (esxVI_String_AppendValueToList(&propertyNameList, "runtime.powerState") < 0 || - esxVI_LookupVirtualMachineByUuid(priv->host, domain->uuid, + esxVI_LookupVirtualMachineByUuid(priv->primary, domain->uuid, propertyNameList, &virtualMachine, esxVI_Occurrence_RequiredItem) < 0 || esxVI_GetVirtualMachinePowerState(virtualMachine, &powerState) < 0) { @@ -1420,7 +1507,7 @@ esxDomainShutdown(virDomainPtr domain) goto cleanup; } - if (esxVI_ShutdownGuest(priv->host, virtualMachine->obj) < 0) { + if (esxVI_ShutdownGuest(priv->primary, virtualMachine->obj) < 0) { goto cleanup; } @@ -1444,13 +1531,13 @@ esxDomainReboot(virDomainPtr domain, unsigned int flags ATTRIBUTE_UNUSED) esxVI_String *propertyNameList = NULL; esxVI_VirtualMachinePowerState powerState; - if (esxVI_EnsureSession(priv->host) < 0) { + if (esxVI_EnsureSession(priv->primary) < 0) { return -1; } if (esxVI_String_AppendValueToList(&propertyNameList, "runtime.powerState") < 0 || - esxVI_LookupVirtualMachineByUuid(priv->host, domain->uuid, + esxVI_LookupVirtualMachineByUuid(priv->primary, domain->uuid, propertyNameList, &virtualMachine, esxVI_Occurrence_RequiredItem) < 0 || esxVI_GetVirtualMachinePowerState(virtualMachine, &powerState) < 0) { @@ -1463,7 +1550,7 @@ esxDomainReboot(virDomainPtr domain, unsigned int flags ATTRIBUTE_UNUSED) goto cleanup; } - if (esxVI_RebootGuest(priv->host, virtualMachine->obj) < 0) { + if (esxVI_RebootGuest(priv->primary, virtualMachine->obj) < 0) { goto cleanup; } @@ -1562,13 +1649,13 @@ esxDomainGetMaxMemory(virDomainPtr domain) esxVI_DynamicProperty *dynamicProperty = NULL; unsigned long memoryMB = 0; - if (esxVI_EnsureSession(priv->host) < 0) { + if (esxVI_EnsureSession(priv->primary) < 0) { return 0; } if (esxVI_String_AppendValueToList(&propertyNameList, "config.hardware.memoryMB") < 0 || - esxVI_LookupVirtualMachineByUuid(priv->host, domain->uuid, + esxVI_LookupVirtualMachineByUuid(priv->primary, domain->uuid, propertyNameList, &virtualMachine, esxVI_Occurrence_RequiredItem) < 0) { goto cleanup; @@ -1615,12 +1702,12 @@ esxDomainSetMaxMemory(virDomainPtr domain, unsigned long memory) esxVI_ManagedObjectReference *task = NULL; esxVI_TaskInfoState taskInfoState; - if (esxVI_EnsureSession(priv->host) < 0) { + if (esxVI_EnsureSession(priv->primary) < 0) { return -1; } if (esxVI_LookupVirtualMachineByUuidAndPrepareForTask - (priv->host, domain->uuid, NULL, &virtualMachine, + (priv->primary, domain->uuid, NULL, &virtualMachine, priv->autoAnswer) < 0 || esxVI_VirtualMachineConfigSpec_Alloc(&spec) < 0 || esxVI_Long_Alloc(&spec->memoryMB) < 0) { @@ -1630,9 +1717,9 @@ esxDomainSetMaxMemory(virDomainPtr domain, unsigned long memory) spec->memoryMB->value = memory / 1024; /* Scale from kilobytes to megabytes */ - if (esxVI_ReconfigVM_Task(priv->host, virtualMachine->obj, spec, + if (esxVI_ReconfigVM_Task(priv->primary, virtualMachine->obj, spec, &task) < 0 || - esxVI_WaitForTaskCompletion(priv->host, task, domain->uuid, + esxVI_WaitForTaskCompletion(priv->primary, task, domain->uuid, priv->autoAnswer, &taskInfoState) < 0) { goto cleanup; } @@ -1665,12 +1752,12 @@ esxDomainSetMemory(virDomainPtr domain, unsigned long memory) esxVI_ManagedObjectReference *task = NULL; esxVI_TaskInfoState taskInfoState; - if (esxVI_EnsureSession(priv->host) < 0) { + if (esxVI_EnsureSession(priv->primary) < 0) { return -1; } if (esxVI_LookupVirtualMachineByUuidAndPrepareForTask - (priv->host, domain->uuid, NULL, &virtualMachine, + (priv->primary, domain->uuid, NULL, &virtualMachine, priv->autoAnswer) < 0 || esxVI_VirtualMachineConfigSpec_Alloc(&spec) < 0 || esxVI_ResourceAllocationInfo_Alloc(&spec->memoryAllocation) < 0 || @@ -1681,9 +1768,9 @@ esxDomainSetMemory(virDomainPtr domain, unsigned long memory) spec->memoryAllocation->limit->value = memory / 1024; /* Scale from kilobytes to megabytes */ - if (esxVI_ReconfigVM_Task(priv->host, virtualMachine->obj, spec, + if (esxVI_ReconfigVM_Task(priv->primary, virtualMachine->obj, spec, &task) < 0 || - esxVI_WaitForTaskCompletion(priv->host, task, domain->uuid, + esxVI_WaitForTaskCompletion(priv->primary, task, domain->uuid, priv->autoAnswer, &taskInfoState) < 0) { goto cleanup; } @@ -1731,7 +1818,7 @@ esxDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info) memset(info, 0, sizeof (*info)); - if (esxVI_EnsureSession(priv->host) < 0) { + if (esxVI_EnsureSession(priv->primary) < 0) { return -1; } @@ -1740,7 +1827,7 @@ esxDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info) "config.hardware.memoryMB\0" "config.hardware.numCPU\0" "config.memoryAllocation.limit\0") < 0 || - esxVI_LookupVirtualMachineByUuid(priv->host, domain->uuid, + esxVI_LookupVirtualMachineByUuid(priv->primary, domain->uuid, propertyNameList, &virtualMachine, esxVI_Occurrence_RequiredItem) < 0) { goto cleanup; @@ -1793,157 +1880,160 @@ esxDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info) info->memory = memory_limit < 0 ? info->maxMem : memory_limit; /* Verify the cached 'used CPU time' performance counter ID */ - if (info->state == VIR_DOMAIN_RUNNING && priv->usedCpuTimeCounterId >= 0) { - if (esxVI_Int_Alloc(&counterId) < 0) { - goto cleanup; - } + /* FIXME: Currently no host for a vpx:// connection */ + if (priv->host != NULL) { + if (info->state == VIR_DOMAIN_RUNNING && priv->usedCpuTimeCounterId >= 0) { + if (esxVI_Int_Alloc(&counterId) < 0) { + goto cleanup; + } - counterId->value = priv->usedCpuTimeCounterId; + counterId->value = priv->usedCpuTimeCounterId; - if (esxVI_Int_AppendToList(&counterIdList, counterId) < 0) { - goto cleanup; - } + if (esxVI_Int_AppendToList(&counterIdList, counterId) < 0) { + goto cleanup; + } - if (esxVI_QueryPerfCounter(priv->host, counterIdList, - &perfCounterInfo) < 0) { - goto cleanup; - } + if (esxVI_QueryPerfCounter(priv->host, counterIdList, + &perfCounterInfo) < 0) { + goto cleanup; + } - if (STRNEQ(perfCounterInfo->groupInfo->key, "cpu") || - STRNEQ(perfCounterInfo->nameInfo->key, "used") || - STRNEQ(perfCounterInfo->unitInfo->key, "millisecond")) { - VIR_DEBUG("Cached usedCpuTimeCounterId %d is invalid", - priv->usedCpuTimeCounterId); + if (STRNEQ(perfCounterInfo->groupInfo->key, "cpu") || + STRNEQ(perfCounterInfo->nameInfo->key, "used") || + STRNEQ(perfCounterInfo->unitInfo->key, "millisecond")) { + VIR_DEBUG("Cached usedCpuTimeCounterId %d is invalid", + priv->usedCpuTimeCounterId); - priv->usedCpuTimeCounterId = -1; + priv->usedCpuTimeCounterId = -1; + } + + esxVI_Int_Free(&counterIdList); + esxVI_PerfCounterInfo_Free(&perfCounterInfo); } - esxVI_Int_Free(&counterIdList); - esxVI_PerfCounterInfo_Free(&perfCounterInfo); - } + /* + * Query the PerformanceManager for the 'used CPU time' performance + * counter ID and cache it, if it's not already cached. + */ + if (info->state == VIR_DOMAIN_RUNNING && priv->usedCpuTimeCounterId < 0) { + if (esxVI_QueryAvailablePerfMetric(priv->host, virtualMachine->obj, + NULL, NULL, NULL, + &perfMetricIdList) < 0) { + goto cleanup; + } - /* - * Query the PerformanceManager for the 'used CPU time' performance - * counter ID and cache it, if it's not already cached. - */ - if (info->state == VIR_DOMAIN_RUNNING && priv->usedCpuTimeCounterId < 0) { - if (esxVI_QueryAvailablePerfMetric(priv->host, virtualMachine->obj, - NULL, NULL, NULL, - &perfMetricIdList) < 0) { - goto cleanup; - } + for (perfMetricId = perfMetricIdList; perfMetricId != NULL; + perfMetricId = perfMetricId->_next) { + VIR_DEBUG("perfMetricId counterId %d, instance '%s'", + perfMetricId->counterId->value, perfMetricId->instance); - for (perfMetricId = perfMetricIdList; perfMetricId != NULL; - perfMetricId = perfMetricId->_next) { - VIR_DEBUG("perfMetricId counterId %d, instance '%s'", - perfMetricId->counterId->value, perfMetricId->instance); + counterId = NULL; - counterId = NULL; + if (esxVI_Int_DeepCopy(&counterId, perfMetricId->counterId) < 0 || + esxVI_Int_AppendToList(&counterIdList, counterId) < 0) { + goto cleanup; + } + } - if (esxVI_Int_DeepCopy(&counterId, perfMetricId->counterId) < 0 || - esxVI_Int_AppendToList(&counterIdList, counterId) < 0) { + if (esxVI_QueryPerfCounter(priv->host, counterIdList, + &perfCounterInfoList) < 0) { goto cleanup; } - } - if (esxVI_QueryPerfCounter(priv->host, counterIdList, - &perfCounterInfoList) < 0) { - goto cleanup; - } - - for (perfCounterInfo = perfCounterInfoList; perfCounterInfo != NULL; - perfCounterInfo = perfCounterInfo->_next) { - VIR_DEBUG("perfCounterInfo key %d, nameInfo '%s', groupInfo '%s', " - "unitInfo '%s', rollupType %d, statsType %d", - perfCounterInfo->key->value, - perfCounterInfo->nameInfo->key, - perfCounterInfo->groupInfo->key, - perfCounterInfo->unitInfo->key, - perfCounterInfo->rollupType, - perfCounterInfo->statsType); - - if (STREQ(perfCounterInfo->groupInfo->key, "cpu") && - STREQ(perfCounterInfo->nameInfo->key, "used") && - STREQ(perfCounterInfo->unitInfo->key, "millisecond")) { - priv->usedCpuTimeCounterId = perfCounterInfo->key->value; - break; + for (perfCounterInfo = perfCounterInfoList; perfCounterInfo != NULL; + perfCounterInfo = perfCounterInfo->_next) { + VIR_DEBUG("perfCounterInfo key %d, nameInfo '%s', groupInfo '%s', " + "unitInfo '%s', rollupType %d, statsType %d", + perfCounterInfo->key->value, + perfCounterInfo->nameInfo->key, + perfCounterInfo->groupInfo->key, + perfCounterInfo->unitInfo->key, + perfCounterInfo->rollupType, + perfCounterInfo->statsType); + + if (STREQ(perfCounterInfo->groupInfo->key, "cpu") && + STREQ(perfCounterInfo->nameInfo->key, "used") && + STREQ(perfCounterInfo->unitInfo->key, "millisecond")) { + priv->usedCpuTimeCounterId = perfCounterInfo->key->value; + break; + } } - } - if (priv->usedCpuTimeCounterId < 0) { - VIR_WARN0("Could not find 'used CPU time' performance counter"); + if (priv->usedCpuTimeCounterId < 0) { + VIR_WARN0("Could not find 'used CPU time' performance counter"); + } } - } - - /* - * Query the PerformanceManager for the 'used CPU time' performance - * counter value. - */ - if (info->state == VIR_DOMAIN_RUNNING && priv->usedCpuTimeCounterId >= 0) { - VIR_DEBUG("usedCpuTimeCounterId %d BEGIN", priv->usedCpuTimeCounterId); - if (esxVI_PerfQuerySpec_Alloc(&querySpec) < 0 || - esxVI_Int_Alloc(&querySpec->maxSample) < 0 || - esxVI_PerfMetricId_Alloc(&querySpec->metricId) < 0 || - esxVI_Int_Alloc(&querySpec->metricId->counterId) < 0) { - goto cleanup; - } + /* + * Query the PerformanceManager for the 'used CPU time' performance + * counter value. + */ + if (info->state == VIR_DOMAIN_RUNNING && priv->usedCpuTimeCounterId >= 0) { + VIR_DEBUG("usedCpuTimeCounterId %d BEGIN", priv->usedCpuTimeCounterId); - querySpec->entity = virtualMachine->obj; - querySpec->maxSample->value = 1; - querySpec->metricId->counterId->value = priv->usedCpuTimeCounterId; - querySpec->metricId->instance = (char *)""; - querySpec->format = (char *)"normal"; + if (esxVI_PerfQuerySpec_Alloc(&querySpec) < 0 || + esxVI_Int_Alloc(&querySpec->maxSample) < 0 || + esxVI_PerfMetricId_Alloc(&querySpec->metricId) < 0 || + esxVI_Int_Alloc(&querySpec->metricId->counterId) < 0) { + goto cleanup; + } - if (esxVI_QueryPerf(priv->host, querySpec, - &perfEntityMetricBaseList) < 0) { - querySpec->entity = NULL; - querySpec->metricId->instance = NULL; - querySpec->format = NULL; - goto cleanup; - } + querySpec->entity = virtualMachine->obj; + querySpec->maxSample->value = 1; + querySpec->metricId->counterId->value = priv->usedCpuTimeCounterId; + querySpec->metricId->instance = (char *)""; + querySpec->format = (char *)"normal"; + + if (esxVI_QueryPerf(priv->host, querySpec, + &perfEntityMetricBaseList) < 0) { + querySpec->entity = NULL; + querySpec->metricId->instance = NULL; + querySpec->format = NULL; + goto cleanup; + } - for (perfEntityMetricBase = perfEntityMetricBaseList; - perfEntityMetricBase != NULL; - perfEntityMetricBase = perfEntityMetricBase->_next) { - VIR_DEBUG0("perfEntityMetric ..."); + for (perfEntityMetricBase = perfEntityMetricBaseList; + perfEntityMetricBase != NULL; + perfEntityMetricBase = perfEntityMetricBase->_next) { + VIR_DEBUG0("perfEntityMetric ..."); - perfEntityMetric = - esxVI_PerfEntityMetric_DynamicCast(perfEntityMetricBase); + perfEntityMetric = + esxVI_PerfEntityMetric_DynamicCast(perfEntityMetricBase); - if (perfMetricIntSeries == NULL) { - VIR_ERROR0(_("QueryPerf returned object with unexpected type")); - } + if (perfMetricIntSeries == NULL) { + VIR_ERROR0(_("QueryPerf returned object with unexpected type")); + } - perfMetricIntSeries = - esxVI_PerfMetricIntSeries_DynamicCast(perfEntityMetric->value); + perfMetricIntSeries = + esxVI_PerfMetricIntSeries_DynamicCast(perfEntityMetric->value); - if (perfMetricIntSeries == NULL) { - VIR_ERROR0(_("QueryPerf returned object with unexpected type")); - } + if (perfMetricIntSeries == NULL) { + VIR_ERROR0(_("QueryPerf returned object with unexpected type")); + } - for (; perfMetricIntSeries != NULL; - perfMetricIntSeries = perfMetricIntSeries->_next) { - VIR_DEBUG0("perfMetricIntSeries ..."); + for (; perfMetricIntSeries != NULL; + perfMetricIntSeries = perfMetricIntSeries->_next) { + VIR_DEBUG0("perfMetricIntSeries ..."); - for (value = perfMetricIntSeries->value; - value != NULL; - value = value->_next) { - VIR_DEBUG("value %lld", (long long int)value->value); + for (value = perfMetricIntSeries->value; + value != NULL; + value = value->_next) { + VIR_DEBUG("value %lld", (long long int)value->value); + } } } - } - querySpec->entity = NULL; - querySpec->metricId->instance = NULL; - querySpec->format = NULL; + querySpec->entity = NULL; + querySpec->metricId->instance = NULL; + querySpec->format = NULL; - VIR_DEBUG("usedCpuTimeCounterId %d END", priv->usedCpuTimeCounterId); + VIR_DEBUG("usedCpuTimeCounterId %d END", priv->usedCpuTimeCounterId); - /* - * FIXME: Cannot map between realtive used-cpu-time and absolute - * info->cpuTime - */ + /* + * FIXME: Cannot map between realtive used-cpu-time and absolute + * info->cpuTime + */ + } } result = 0; @@ -1979,7 +2069,7 @@ esxDomainSetVcpus(virDomainPtr domain, unsigned int nvcpus) return -1; } - if (esxVI_EnsureSession(priv->host) < 0) { + if (esxVI_EnsureSession(priv->primary) < 0) { return -1; } @@ -1998,7 +2088,7 @@ esxDomainSetVcpus(virDomainPtr domain, unsigned int nvcpus) } if (esxVI_LookupVirtualMachineByUuidAndPrepareForTask - (priv->host, domain->uuid, NULL, &virtualMachine, + (priv->primary, domain->uuid, NULL, &virtualMachine, priv->autoAnswer) < 0 || esxVI_VirtualMachineConfigSpec_Alloc(&spec) < 0 || esxVI_Int_Alloc(&spec->numCPUs) < 0) { @@ -2007,9 +2097,9 @@ esxDomainSetVcpus(virDomainPtr domain, unsigned int nvcpus) spec->numCPUs->value = nvcpus; - if (esxVI_ReconfigVM_Task(priv->host, virtualMachine->obj, spec, + if (esxVI_ReconfigVM_Task(priv->primary, virtualMachine->obj, spec, &task) < 0 || - esxVI_WaitForTaskCompletion(priv->host, task, domain->uuid, + esxVI_WaitForTaskCompletion(priv->primary, task, domain->uuid, priv->autoAnswer, &taskInfoState) < 0) { goto cleanup; } @@ -2046,6 +2136,13 @@ esxDomainGetMaxVcpus(virDomainPtr domain) priv->maxVcpus = -1; + if (priv->host == NULL) { + /* FIXME: Currently no host for a vpx:// connection */ + ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", + _("MaxVCPUs value is not available for a vpx:// connection")); + return -1; + } + if (esxVI_EnsureSession(priv->host) < 0) { return -1; } @@ -2093,9 +2190,11 @@ esxDomainDumpXML(virDomainPtr domain, int flags) { esxPrivate *priv = domain->conn->privateData; esxVI_String *propertyNameList = NULL; + esxVI_ObjectContent *datacenter = NULL; esxVI_ObjectContent *virtualMachine = NULL; esxVI_DynamicProperty *dynamicProperty = NULL; const char *vmPathName = NULL; + char *datacenterName = NULL; char *datastoreName = NULL; char *directoryName = NULL; char *fileName = NULL; @@ -2105,13 +2204,24 @@ esxDomainDumpXML(virDomainPtr domain, int flags) virDomainDefPtr def = NULL; char *xml = NULL; - if (esxVI_EnsureSession(priv->host) < 0) { + if (esxVI_EnsureSession(priv->primary) < 0) { return NULL; } + if (esxVI_String_AppendValueToList(&propertyNameList, "name") < 0 || + esxVI_LookupObjectContentByType(priv->primary, priv->primary->datacenter, + "Datacenter", propertyNameList, + esxVI_Boolean_False, &datacenter) < 0 || + esxVI_GetStringValue(datacenter, "name", &datacenterName, + esxVI_Occurrence_RequiredItem) < 0) { + goto cleanup; + } + + esxVI_String_Free(&propertyNameList); + if (esxVI_String_AppendValueToList(&propertyNameList, "config.files.vmPathName") < 0 || - esxVI_LookupVirtualMachineByUuid(priv->host, domain->uuid, + esxVI_LookupVirtualMachineByUuid(priv->primary, domain->uuid, propertyNameList, &virtualMachine, esxVI_Occurrence_RequiredItem) < 0) { goto cleanup; @@ -2145,7 +2255,7 @@ esxDomainDumpXML(virDomainPtr domain, int flags) virBufferURIEncodeString(&buffer, fileName); virBufferAddLit(&buffer, "?dcPath="); - virBufferURIEncodeString(&buffer, priv->host->datacenter->value); + virBufferURIEncodeString(&buffer, datacenterName); virBufferAddLit(&buffer, "&dsName="); virBufferURIEncodeString(&buffer, datastoreName); @@ -2156,12 +2266,12 @@ esxDomainDumpXML(virDomainPtr domain, int flags) url = virBufferContentAndReset(&buffer); - if (esxVI_Context_DownloadFile(priv->host, url, &vmx) < 0) { + if (esxVI_Context_DownloadFile(priv->primary, url, &vmx) < 0) { goto cleanup; } - def = esxVMX_ParseConfig(priv->host, priv->caps, vmx, datastoreName, - directoryName, priv->host->productVersion); + def = esxVMX_ParseConfig(priv->primary, priv->caps, vmx, datastoreName, + directoryName, priv->primary->productVersion); if (def != NULL) { xml = virDomainDefFormat(def, flags); @@ -2173,6 +2283,7 @@ esxDomainDumpXML(virDomainPtr domain, int flags) } esxVI_String_Free(&propertyNameList); + esxVI_ObjectContent_Free(&datacenter); esxVI_ObjectContent_Free(&virtualMachine); VIR_FREE(datastoreName); VIR_FREE(directoryName); @@ -2201,8 +2312,8 @@ esxDomainXMLFromNative(virConnectPtr conn, const char *nativeFormat, return NULL; } - def = esxVMX_ParseConfig(priv->host, priv->caps, nativeConfig, "?", "?", - priv->host->productVersion); + def = esxVMX_ParseConfig(priv->primary, priv->caps, nativeConfig, "?", "?", + priv->primary->productVersion); if (def != NULL) { xml = virDomainDefFormat(def, VIR_DOMAIN_XML_INACTIVE); @@ -2236,8 +2347,8 @@ esxDomainXMLToNative(virConnectPtr conn, const char *nativeFormat, return NULL; } - vmx = esxVMX_FormatConfig(priv->host, priv->caps, def, - priv->host->productVersion); + vmx = esxVMX_FormatConfig(priv->primary, priv->caps, def, + priv->primary->productVersion); virDomainDefFree(def); @@ -2268,14 +2379,14 @@ esxListDefinedDomains(virConnectPtr conn, char **const names, int maxnames) return 0; } - if (esxVI_EnsureSession(priv->host) < 0) { + if (esxVI_EnsureSession(priv->primary) < 0) { return -1; } if (esxVI_String_AppendValueListToList(&propertyNameList, "name\0" "runtime.powerState\0") < 0 || - esxVI_LookupObjectContentByType(priv->host, priv->host->vmFolder, + esxVI_LookupObjectContentByType(priv->primary, priv->primary->vmFolder, "VirtualMachine", propertyNameList, esxVI_Boolean_True, &virtualMachineList) < 0) { @@ -2343,12 +2454,12 @@ esxNumberOfDefinedDomains(virConnectPtr conn) { esxPrivate *priv = conn->privateData; - if (esxVI_EnsureSession(priv->host) < 0) { + if (esxVI_EnsureSession(priv->primary) < 0) { return -1; } return esxVI_LookupNumberOfDomainsByPowerState - (priv->host, esxVI_VirtualMachinePowerState_PoweredOn, + (priv->primary, esxVI_VirtualMachinePowerState_PoweredOn, esxVI_Boolean_True); } @@ -2367,14 +2478,14 @@ esxDomainCreateWithFlags(virDomainPtr domain, unsigned int flags) virCheckFlags(0, -1); - if (esxVI_EnsureSession(priv->host) < 0) { + if (esxVI_EnsureSession(priv->primary) < 0) { return -1; } if (esxVI_String_AppendValueToList(&propertyNameList, "runtime.powerState") < 0 || esxVI_LookupVirtualMachineByUuidAndPrepareForTask - (priv->host, domain->uuid, propertyNameList, &virtualMachine, + (priv->primary, domain->uuid, propertyNameList, &virtualMachine, priv->autoAnswer) < 0 || esxVI_GetVirtualMachinePowerState(virtualMachine, &powerState) < 0) { @@ -2387,9 +2498,9 @@ esxDomainCreateWithFlags(virDomainPtr domain, unsigned int flags) goto cleanup; } - if (esxVI_PowerOnVM_Task(priv->host, virtualMachine->obj, NULL, + if (esxVI_PowerOnVM_Task(priv->primary, virtualMachine->obj, NULL, &task) < 0 || - esxVI_WaitForTaskCompletion(priv->host, task, domain->uuid, + esxVI_WaitForTaskCompletion(priv->primary, task, domain->uuid, priv->autoAnswer, &taskInfoState) < 0) { goto cleanup; } @@ -2437,6 +2548,13 @@ esxDomainDefineXML(virConnectPtr conn, const char *xml ATTRIBUTE_UNUSED) esxVI_TaskInfoState taskInfoState; virDomainPtr domain = NULL; + if (priv->host == NULL) { + /* FIXME: Currently no host for a vpx:// connection */ + ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", + _("Could not define domain with a vpx:// connection")); + return NULL; + } + if (esxVI_EnsureSession(priv->host) < 0) { return NULL; } @@ -2737,7 +2855,7 @@ esxDomainGetSchedulerParameters(virDomainPtr domain, return -1; } - if (esxVI_EnsureSession(priv->host) < 0) { + if (esxVI_EnsureSession(priv->primary) < 0) { return -1; } @@ -2745,7 +2863,7 @@ esxDomainGetSchedulerParameters(virDomainPtr domain, "config.cpuAllocation.reservation\0" "config.cpuAllocation.limit\0" "config.cpuAllocation.shares\0") < 0 || - esxVI_LookupVirtualMachineByUuid(priv->host, domain->uuid, + esxVI_LookupVirtualMachineByUuid(priv->primary, domain->uuid, propertyNameList, &virtualMachine, esxVI_Occurrence_RequiredItem) < 0) { goto cleanup; @@ -2856,12 +2974,12 @@ esxDomainSetSchedulerParameters(virDomainPtr domain, esxVI_TaskInfoState taskInfoState; int i; - if (esxVI_EnsureSession(priv->host) < 0) { + if (esxVI_EnsureSession(priv->primary) < 0) { return -1; } if (esxVI_LookupVirtualMachineByUuidAndPrepareForTask - (priv->host, domain->uuid, NULL, &virtualMachine, + (priv->primary, domain->uuid, NULL, &virtualMachine, priv->autoAnswer) < 0 || esxVI_VirtualMachineConfigSpec_Alloc(&spec) < 0 || esxVI_ResourceAllocationInfo_Alloc(&spec->cpuAllocation) < 0) { @@ -2944,9 +3062,9 @@ esxDomainSetSchedulerParameters(virDomainPtr domain, } } - if (esxVI_ReconfigVM_Task(priv->host, virtualMachine->obj, spec, + if (esxVI_ReconfigVM_Task(priv->primary, virtualMachine->obj, spec, &task) < 0 || - esxVI_WaitForTaskCompletion(priv->host, task, domain->uuid, + esxVI_WaitForTaskCompletion(priv->primary, task, domain->uuid, priv->autoAnswer, &taskInfoState) < 0) { goto cleanup; } @@ -3152,6 +3270,13 @@ esxNodeGetFreeMemory(virConnectPtr conn) esxVI_DynamicProperty *dynamicProperty = NULL; esxVI_ResourcePoolResourceUsage *resourcePoolResourceUsage = NULL; + if (priv->host == NULL) { + /* FIXME: Currently no host for a vpx:// connection */ + ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", + _("Could not retrieve free memory for a vpx:// connection")); + return 0; + } + if (esxVI_EnsureSession(priv->host) < 0) { return 0; } @@ -3251,13 +3376,13 @@ esxDomainIsActive(virDomainPtr domain) esxVI_String *propertyNameList = NULL; esxVI_VirtualMachinePowerState powerState; - if (esxVI_EnsureSession(priv->host) < 0) { + if (esxVI_EnsureSession(priv->primary) < 0) { return -1; } if (esxVI_String_AppendValueToList(&propertyNameList, "runtime.powerState") < 0 || - esxVI_LookupVirtualMachineByUuid(priv->host, domain->uuid, + esxVI_LookupVirtualMachineByUuid(priv->primary, domain->uuid, propertyNameList, &virtualMachine, esxVI_Occurrence_RequiredItem) < 0 || esxVI_GetVirtualMachinePowerState(virtualMachine, &powerState) < 0) { @@ -3304,7 +3429,7 @@ esxDomainSnapshotCreateXML(virDomainPtr domain, const char *xmlDesc, virCheckFlags(0, NULL); - if (esxVI_EnsureSession(priv->host) < 0) { + if (esxVI_EnsureSession(priv->primary) < 0) { return NULL; } @@ -3315,9 +3440,9 @@ esxDomainSnapshotCreateXML(virDomainPtr domain, const char *xmlDesc, } if (esxVI_LookupVirtualMachineByUuidAndPrepareForTask - (priv->host, domain->uuid, NULL, &virtualMachine, + (priv->primary, domain->uuid, NULL, &virtualMachine, priv->autoAnswer) < 0 || - esxVI_LookupRootSnapshotTreeList(priv->host, domain->uuid, + esxVI_LookupRootSnapshotTreeList(priv->primary, domain->uuid, &rootSnapshotList) < 0 || esxVI_GetSnapshotTreeByName(rootSnapshotList, def->name, &snapshotTree, &snapshotTreeParent, @@ -3331,11 +3456,11 @@ esxDomainSnapshotCreateXML(virDomainPtr domain, const char *xmlDesc, goto cleanup; } - if (esxVI_CreateSnapshot_Task(priv->host, virtualMachine->obj, + if (esxVI_CreateSnapshot_Task(priv->primary, virtualMachine->obj, def->name, def->description, esxVI_Boolean_True, esxVI_Boolean_False, &task) < 0 || - esxVI_WaitForTaskCompletion(priv->host, task, domain->uuid, + esxVI_WaitForTaskCompletion(priv->primary, task, domain->uuid, priv->autoAnswer, &taskInfoState) < 0) { goto cleanup; } @@ -3374,11 +3499,11 @@ esxDomainSnapshotDumpXML(virDomainSnapshotPtr snapshot, memset(&def, 0, sizeof (def)); - if (esxVI_EnsureSession(priv->host) < 0) { + if (esxVI_EnsureSession(priv->primary) < 0) { return NULL; } - if (esxVI_LookupRootSnapshotTreeList(priv->host, snapshot->domain->uuid, + if (esxVI_LookupRootSnapshotTreeList(priv->primary, snapshot->domain->uuid, &rootSnapshotList) < 0 || esxVI_GetSnapshotTreeByName(rootSnapshotList, snapshot->name, &snapshotTree, &snapshotTreeParent, @@ -3419,11 +3544,11 @@ esxDomainSnapshotNum(virDomainPtr domain, unsigned int flags) virCheckFlags(0, -1); - if (esxVI_EnsureSession(priv->host) < 0) { + if (esxVI_EnsureSession(priv->primary) < 0) { return -1; } - if (esxVI_LookupRootSnapshotTreeList(priv->host, domain->uuid, + if (esxVI_LookupRootSnapshotTreeList(priv->primary, domain->uuid, &rootSnapshotTreeList) < 0) { return -1; } @@ -3456,11 +3581,11 @@ esxDomainSnapshotListNames(virDomainPtr domain, char **names, int nameslen, return 0; } - if (esxVI_EnsureSession(priv->host) < 0) { + if (esxVI_EnsureSession(priv->primary) < 0) { return -1; } - if (esxVI_LookupRootSnapshotTreeList(priv->host, domain->uuid, + if (esxVI_LookupRootSnapshotTreeList(priv->primary, domain->uuid, &rootSnapshotTreeList) < 0) { return -1; } @@ -3486,11 +3611,11 @@ esxDomainSnapshotLookupByName(virDomainPtr domain, const char *name, virCheckFlags(0, NULL); - if (esxVI_EnsureSession(priv->host) < 0) { + if (esxVI_EnsureSession(priv->primary) < 0) { return NULL; } - if (esxVI_LookupRootSnapshotTreeList(priv->host, domain->uuid, + if (esxVI_LookupRootSnapshotTreeList(priv->primary, domain->uuid, &rootSnapshotTreeList) < 0 || esxVI_GetSnapshotTreeByName(rootSnapshotTreeList, name, &snapshotTree, &snapshotTreeParent, @@ -3516,11 +3641,11 @@ esxDomainHasCurrentSnapshot(virDomainPtr domain, unsigned int flags) virCheckFlags(0, -1); - if (esxVI_EnsureSession(priv->host) < 0) { + if (esxVI_EnsureSession(priv->primary) < 0) { return -1; } - if (esxVI_LookupCurrentSnapshotTree(priv->host, domain->uuid, + if (esxVI_LookupCurrentSnapshotTree(priv->primary, domain->uuid, ¤tSnapshotTree, esxVI_Occurrence_OptionalItem) < 0) { return -1; @@ -3545,11 +3670,11 @@ esxDomainSnapshotCurrent(virDomainPtr domain, unsigned int flags) virCheckFlags(0, NULL); - if (esxVI_EnsureSession(priv->host) < 0) { + if (esxVI_EnsureSession(priv->primary) < 0) { return NULL; } - if (esxVI_LookupCurrentSnapshotTree(priv->host, domain->uuid, + if (esxVI_LookupCurrentSnapshotTree(priv->primary, domain->uuid, ¤tSnapshotTree, esxVI_Occurrence_RequiredItem) < 0) { return NULL; @@ -3577,11 +3702,11 @@ esxDomainRevertToSnapshot(virDomainSnapshotPtr snapshot, unsigned int flags) virCheckFlags(0, -1); - if (esxVI_EnsureSession(priv->host) < 0) { + if (esxVI_EnsureSession(priv->primary) < 0) { return -1; } - if (esxVI_LookupRootSnapshotTreeList(priv->host, snapshot->domain->uuid, + if (esxVI_LookupRootSnapshotTreeList(priv->primary, snapshot->domain->uuid, &rootSnapshotList) < 0 || esxVI_GetSnapshotTreeByName(rootSnapshotList, snapshot->name, &snapshotTree, &snapshotTreeParent, @@ -3589,9 +3714,9 @@ esxDomainRevertToSnapshot(virDomainSnapshotPtr snapshot, unsigned int flags) goto cleanup; } - if (esxVI_RevertToSnapshot_Task(priv->host, snapshotTree->snapshot, NULL, + if (esxVI_RevertToSnapshot_Task(priv->primary, snapshotTree->snapshot, NULL, &task) < 0 || - esxVI_WaitForTaskCompletion(priv->host, task, snapshot->domain->uuid, + esxVI_WaitForTaskCompletion(priv->primary, task, snapshot->domain->uuid, priv->autoAnswer, &taskInfoState) < 0) { goto cleanup; } @@ -3627,7 +3752,7 @@ esxDomainSnapshotDelete(virDomainSnapshotPtr snapshot, unsigned int flags) virCheckFlags(VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN, -1); - if (esxVI_EnsureSession(priv->host) < 0) { + if (esxVI_EnsureSession(priv->primary) < 0) { return -1; } @@ -3635,7 +3760,7 @@ esxDomainSnapshotDelete(virDomainSnapshotPtr snapshot, unsigned int flags) removeChildren = esxVI_Boolean_True; } - if (esxVI_LookupRootSnapshotTreeList(priv->host, snapshot->domain->uuid, + if (esxVI_LookupRootSnapshotTreeList(priv->primary, snapshot->domain->uuid, &rootSnapshotList) < 0 || esxVI_GetSnapshotTreeByName(rootSnapshotList, snapshot->name, &snapshotTree, &snapshotTreeParent, @@ -3643,9 +3768,9 @@ esxDomainSnapshotDelete(virDomainSnapshotPtr snapshot, unsigned int flags) goto cleanup; } - if (esxVI_RemoveSnapshot_Task(priv->host, snapshotTree->snapshot, + if (esxVI_RemoveSnapshot_Task(priv->primary, snapshotTree->snapshot, removeChildren, &task) < 0 || - esxVI_WaitForTaskCompletion(priv->host, task, snapshot->domain->uuid, + esxVI_WaitForTaskCompletion(priv->primary, task, snapshot->domain->uuid, priv->autoAnswer, &taskInfoState) < 0) { goto cleanup; } diff --git a/src/esx/esx_private.h b/src/esx/esx_private.h index 19955a5..6c7edb1 100644 --- a/src/esx/esx_private.h +++ b/src/esx/esx_private.h @@ -33,6 +33,7 @@ __LINE__, __VA_ARGS__) typedef struct _esxPrivate { + esxVI_Context *primary; /* points to host or vCenter */ esxVI_Context *host; esxVI_Context *vCenter; virCapsPtr caps; diff --git a/src/esx/esx_storage_driver.c b/src/esx/esx_storage_driver.c index 98e7137..44d7d85 100644 --- a/src/esx/esx_storage_driver.c +++ b/src/esx/esx_storage_driver.c @@ -74,11 +74,11 @@ esxNumberOfStoragePools(virConnectPtr conn) esxVI_ObjectContent *datastoreList = NULL; esxVI_ObjectContent *datastore = NULL; - if (esxVI_EnsureSession(priv->host) < 0) { + if (esxVI_EnsureSession(priv->primary) < 0) { return -1; } - if (esxVI_LookupObjectContentByType(priv->host, priv->host->datacenter, + if (esxVI_LookupObjectContentByType(priv->primary, priv->primary->datacenter, "Datastore", NULL, esxVI_Boolean_True, &datastoreList) < 0) { return -1; @@ -117,13 +117,13 @@ esxListStoragePools(virConnectPtr conn, char **const names, int maxnames) return 0; } - if (esxVI_EnsureSession(priv->host) < 0) { + if (esxVI_EnsureSession(priv->primary) < 0) { return -1; } if (esxVI_String_AppendValueToList(&propertyNameList, "summary.name") < 0 || - esxVI_LookupObjectContentByType(priv->host, priv->host->datacenter, + esxVI_LookupObjectContentByType(priv->primary, priv->primary->datacenter, "Datastore", propertyNameList, esxVI_Boolean_True, &datastoreList) < 0) { @@ -209,7 +209,7 @@ esxStoragePoolLookupByName(virConnectPtr conn, const char *name) char *realName = NULL; virStoragePoolPtr pool = NULL; - if (esxVI_EnsureSession(priv->host) < 0) { + if (esxVI_EnsureSession(priv->primary) < 0) { return NULL; } @@ -217,7 +217,7 @@ esxStoragePoolLookupByName(virConnectPtr conn, const char *name) "summary.accessible\0" "summary.name\0" "summary.url\0") < 0 || - esxVI_LookupDatastoreByName(priv->host, name, + esxVI_LookupDatastoreByName(priv->primary, name, propertyNameList, &datastore, esxVI_Occurrence_RequiredItem) < 0 || esxVI_GetBoolean(datastore, "summary.accessible", @@ -242,7 +242,8 @@ esxStoragePoolLookupByName(virConnectPtr conn, const char *name) * * The 'summary.url' property of an inaccessible datastore is invalid. */ - if (accessible == esxVI_Boolean_True && + /* FIXME: Need to handle this for a vpx:// connection */ + if (accessible == esxVI_Boolean_True && priv->host != NULL && priv->host->productVersion & esxVI_ProductVersion_ESX) { if (esxVI_GetStringValue(datastore, "summary.url", &summaryUrl, esxVI_Occurrence_RequiredItem) < 0) { @@ -307,7 +308,9 @@ esxStoragePoolLookupByUUID(virConnectPtr conn, const unsigned char *uuid) char *name = NULL; virStoragePoolPtr pool = NULL; - if (! (priv->host->productVersion & esxVI_ProductVersion_ESX)) { + /* FIXME: Need to handle this for a vpx:// connection */ + if (priv->host == NULL || + ! (priv->host->productVersion & esxVI_ProductVersion_ESX)) { ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Lookup by UUID is supported on ESX only")); return NULL; @@ -389,13 +392,13 @@ esxStoragePoolRefresh(virStoragePoolPtr pool, unsigned int flags) virCheckFlags(0, -1); - if (esxVI_EnsureSession(priv->host) < 0) { + if (esxVI_EnsureSession(priv->primary) < 0) { return -1; } - if (esxVI_LookupDatastoreByName(priv->host, pool->name, NULL, &datastore, + if (esxVI_LookupDatastoreByName(priv->primary, pool->name, NULL, &datastore, esxVI_Occurrence_RequiredItem) < 0 || - esxVI_RefreshDatastore(priv->host, datastore->obj) < 0) { + esxVI_RefreshDatastore(priv->primary, datastore->obj) < 0) { goto cleanup; } @@ -421,7 +424,7 @@ esxStoragePoolGetInfo(virStoragePoolPtr pool, virStoragePoolInfoPtr info) memset(info, 0, sizeof (*info)); - if (esxVI_EnsureSession(priv->host) < 0) { + if (esxVI_EnsureSession(priv->primary) < 0) { return -1; } @@ -429,7 +432,7 @@ esxStoragePoolGetInfo(virStoragePoolPtr pool, virStoragePoolInfoPtr info) "summary.accessible\0" "summary.capacity\0" "summary.freeSpace\0") < 0 || - esxVI_LookupDatastoreByName(priv->host, pool->name, + esxVI_LookupDatastoreByName(priv->primary, pool->name, propertyNameList, &datastore, esxVI_Occurrence_RequiredItem) < 0 || esxVI_GetBoolean(datastore, "summary.accessible", @@ -494,7 +497,7 @@ esxStoragePoolGetXMLDesc(virStoragePoolPtr pool, unsigned int flags) memset(&def, 0, sizeof (def)); - if (esxVI_EnsureSession(priv->host) < 0) { + if (esxVI_EnsureSession(priv->primary) < 0) { return NULL; } @@ -503,7 +506,7 @@ esxStoragePoolGetXMLDesc(virStoragePoolPtr pool, unsigned int flags) "summary.capacity\0" "summary.freeSpace\0" "info\0") < 0 || - esxVI_LookupDatastoreByName(priv->host, pool->name, + esxVI_LookupDatastoreByName(priv->primary, pool->name, propertyNameList, &datastore, esxVI_Occurrence_RequiredItem) < 0 || esxVI_GetBoolean(datastore, "summary.accessible", diff --git a/src/esx/esx_vmx.c b/src/esx/esx_vmx.c index 9035233..e075149 100644 --- a/src/esx/esx_vmx.c +++ b/src/esx/esx_vmx.c @@ -1188,6 +1188,7 @@ esxVMX_ParseConfig(esxVI_Context *ctx, virCapsPtr caps, const char *vmx, */ switch (productVersion) { case esxVI_ProductVersion_ESX35: + case esxVI_ProductVersion_VPX25: if (virtualHW_version != 4) { ESX_ERROR(VIR_ERR_INTERNAL_ERROR, _("Expecting VMX entry 'virtualHW.version' to be 4 " @@ -1200,6 +1201,7 @@ esxVMX_ParseConfig(esxVI_Context *ctx, virCapsPtr caps, const char *vmx, case esxVI_ProductVersion_GSX20: case esxVI_ProductVersion_ESX40: + case esxVI_ProductVersion_VPX40: if (virtualHW_version != 4 && virtualHW_version != 7) { ESX_ERROR(VIR_ERR_INTERNAL_ERROR, _("Expecting VMX entry 'virtualHW.version' to be 4 or 7 " diff --git a/src/libvirt.c b/src/libvirt.c index d1b210d..3ec5724 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -1224,6 +1224,7 @@ do_open (const char *name, STRCASEEQ(ret->uri->scheme, "phyp") || #endif #ifndef WITH_ESX + STRCASEEQ(ret->uri->scheme, "vpx") || STRCASEEQ(ret->uri->scheme, "esx") || STRCASEEQ(ret->uri->scheme, "gsx") || #endif -- 1.7.0.4

On Mon, Jul 19, 2010 at 01:26:10AM +0200, Matthias Bolte wrote:
Add a pointer to the primary context of a connection and use it in all driver functions that don't dependent on the context type. This includes almost all functions that deal with a virDomianPtr. Therefore, using a vpx:// connection allows you to perform all the usual domain related actions like start, destroy, suspend, resume, dumpxml etc.
Some functions that require an explicitly specified ESX server don't work yet. This includes the host UUID, the hostname, the general node info, the max vCPU count and the free memory. Also not working yet are migration and defining new domains. --- docs/drvesx.html.in | 21 +- src/esx/esx_driver.c | 931 ++++++++++++++++++++++++------------------ src/esx/esx_private.h | 1 + src/esx/esx_storage_driver.c | 33 +- src/esx/esx_vmx.c | 2 + src/libvirt.c | 1 + 6 files changed, 562 insertions(+), 427 deletions(-)
diff --git a/docs/drvesx.html.in b/docs/drvesx.html.in index e8cee77..1f2ae4e 100644 --- a/docs/drvesx.html.in +++ b/docs/drvesx.html.in @@ -4,13 +4,14 @@ <p> The libvirt VMware ESX driver can manage VMware ESX/ESXi 3.5/4.0 and VMware GSX 2.0, also called VMware Server 2.0, and possibly later - versions. + versions. <span class="since">Since 0.8.3</span> the driver can also + connect to a VMware vCenter 2.5/4.0 (VPX). </p>
<h2><a name="prereq">Deployment pre-requisites</a></h2> <p> - None. Any out-of-the-box installation of ESX/GSX should work. No + None. Any out-of-the-box installation of VPX/ESX(i)/GSX should work. No preparations are required on the server side, no libvirtd must be installed on the ESX server. The driver uses version 2.5 of the remote, SOAP based @@ -27,10 +28,11 @@ Some example remote connection URIs for the driver are: </p> <pre> -esx://example.com (ESX over HTTPS) -gsx://example.com (GSX over HTTPS) -esx://example.com/?transport=http (ESX over HTTP) -esx://example.com/?no_verify=1 (ESX over HTTPS, but doesn't verify the server's SSL certificate) +vpx://example-vcenter.com (VPX over HTTPS) +esx://example-esx.com (ESX over HTTPS) +gsx://example-gsx.com (GSX over HTTPS) +esx://example-esx.com/?transport=http (ESX over HTTP) +esx://example-esx.com/?no_verify=1 (ESX over HTTPS, but doesn't verify the server's SSL certificate) </pre> <p> <strong>Note</strong>: In contrast to other drivers, the ESX driver is @@ -49,9 +51,9 @@ esx://example.com/?no_verify=1 (ESX over HTTPS, but doesn't verify the serve type://[username@]hostname[:port]/[?extraparameters]
May I suggest a small extra sentence here, explaining how to compose extraparameters ? User may find from lookuing above that they need to use: arg=value but there is no indication on how to separate multiple parameter.
</pre> <p> [...] diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c index 33f421d..5922cb6 100644 --- a/src/esx/esx_driver.c +++ b/src/esx/esx_driver.c @@ -67,6 +67,11 @@ esxSupportsLongMode(esxPrivate *priv) return priv->supportsLongMode; }
+ if (priv->host == NULL) { + /* FIXME: Currently no host for a vpx:// connection */ + return esxVI_Boolean_False; + } +
What about emitting an error in those cases ? [...]
@@ -661,6 +729,11 @@ esxSupportsVMotion(esxPrivate *priv) return priv->supportsVMotion; }
+ if (priv->host == NULL) { + /* FIXME: Currently no host for a vpx:// connection */ + return esxVI_Boolean_False; + } +
I feel ignorant here. I would assume that a vpx:// connection being to a vCenter vould allow to migrate, care to explain :-) ? [...]
@@ -2173,6 +2283,7 @@ esxDomainDumpXML(virDomainPtr domain, int flags) }
esxVI_String_Free(&propertyNameList); + esxVI_ObjectContent_Free(&datacenter); esxVI_ObjectContent_Free(&virtualMachine); VIR_FREE(datastoreName); VIR_FREE(directoryName);
I'm a bit suspicious, I see no virFree(datacenterName) here ... normal ? Okay, overall a very large part of the patch is the change from priv->host to priv->primary, and there is still some TODOs without an error, I assume they will get fixed soon, based on this and after double checking the few points I raised, ACK :-) thanks ! Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

2010/7/19 Daniel Veillard <veillard@redhat.com>:
On Mon, Jul 19, 2010 at 01:26:10AM +0200, Matthias Bolte wrote:
Add a pointer to the primary context of a connection and use it in all driver functions that don't dependent on the context type. This includes almost all functions that deal with a virDomianPtr. Therefore, using a vpx:// connection allows you to perform all the usual domain related actions like start, destroy, suspend, resume, dumpxml etc.
Some functions that require an explicitly specified ESX server don't work yet. This includes the host UUID, the hostname, the general node info, the max vCPU count and the free memory. Also not working yet are migration and defining new domains. --- docs/drvesx.html.in | 21 +- src/esx/esx_driver.c | 931 ++++++++++++++++++++++++------------------ src/esx/esx_private.h | 1 + src/esx/esx_storage_driver.c | 33 +- src/esx/esx_vmx.c | 2 + src/libvirt.c | 1 + 6 files changed, 562 insertions(+), 427 deletions(-)
diff --git a/docs/drvesx.html.in b/docs/drvesx.html.in index e8cee77..1f2ae4e 100644 --- a/docs/drvesx.html.in +++ b/docs/drvesx.html.in @@ -4,13 +4,14 @@ <p> The libvirt VMware ESX driver can manage VMware ESX/ESXi 3.5/4.0 and VMware GSX 2.0, also called VMware Server 2.0, and possibly later - versions. + versions. <span class="since">Since 0.8.3</span> the driver can also + connect to a VMware vCenter 2.5/4.0 (VPX). </p>
<h2><a name="prereq">Deployment pre-requisites</a></h2> <p> - None. Any out-of-the-box installation of ESX/GSX should work. No + None. Any out-of-the-box installation of VPX/ESX(i)/GSX should work. No preparations are required on the server side, no libvirtd must be installed on the ESX server. The driver uses version 2.5 of the remote, SOAP based @@ -27,10 +28,11 @@ Some example remote connection URIs for the driver are: </p> <pre> -esx://example.com (ESX over HTTPS) -gsx://example.com (GSX over HTTPS) -esx://example.com/?transport=http (ESX over HTTP) -esx://example.com/?no_verify=1 (ESX over HTTPS, but doesn't verify the server's SSL certificate) +vpx://example-vcenter.com (VPX over HTTPS) +esx://example-esx.com (ESX over HTTPS) +gsx://example-gsx.com (GSX over HTTPS) +esx://example-esx.com/?transport=http (ESX over HTTP) +esx://example-esx.com/?no_verify=1 (ESX over HTTPS, but doesn't verify the server's SSL certificate) </pre> <p> <strong>Note</strong>: In contrast to other drivers, the ESX driver is @@ -49,9 +51,9 @@ esx://example.com/?no_verify=1 (ESX over HTTPS, but doesn't verify the serve type://[username@]hostname[:port]/[?extraparameters]
May I suggest a small extra sentence here, explaining how to compose extraparameters ? User may find from lookuing above that they need to use:
arg=value
but there is no indication on how to separate multiple parameter.
That's true. I'll add a sentence or two about that.
</pre> <p> [...] diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c index 33f421d..5922cb6 100644 --- a/src/esx/esx_driver.c +++ b/src/esx/esx_driver.c @@ -67,6 +67,11 @@ esxSupportsLongMode(esxPrivate *priv) return priv->supportsLongMode; }
+ if (priv->host == NULL) { + /* FIXME: Currently no host for a vpx:// connection */ + return esxVI_Boolean_False; + } +
What about emitting an error in those cases ?
No error is reported here, because there is no error. I case you connected to a vCenter there is currently no host object that could be used to detect i686 vs x86_64. So the driver just pretends that x86_64 is not supported. The same holds for the other places that are short-circuited like this for a vpx:// connection.
[...]
@@ -661,6 +729,11 @@ esxSupportsVMotion(esxPrivate *priv) return priv->supportsVMotion; }
+ if (priv->host == NULL) { + /* FIXME: Currently no host for a vpx:// connection */ + return esxVI_Boolean_False; + } +
I feel ignorant here. I would assume that a vpx:// connection being to a vCenter vould allow to migrate, care to explain :-) ?
It will, but migration is tricky. Some more details first: An ESX server has one Datacenter, this Datacenter contains one ComputeResource and this ComputeResource has a single HostSystem attached. Migration is performed between HostSystems in general. Given two ESX connections the driver can easily determine the two involved HostSystems. A vCenter server can have multiple Datacenters, each Datacenter can contain multiple ComputeResources. There also might by a special type of ComputeResources, the ClusterComputeResource. A ClusterComputeResource may have multiple HostSystems attached. To make it more complex there is DRS. If DRS is enabled for a ClusterComputeResource then the vCenter server will automatically control the VirtualMachine to HostSystem mapping. In that case you can migrate between ClusterComputeResources and the vCenter will select the destination HostSystem for you. But with the current vpx:// URI you specify the vCenter only, you don't specify the Datacenter or the ComputeResource or the HostSystem yet. Therefore, migration using a vpx:// URI doesn't work yet and I simply short-circuited the VMotion check for a vpx:// connection for now, effectively disabling migration for vpx:// connections. I plan to model the Datacenter/ComputeResource/HostSystem selection via the path part of the URI: vpx://example-vcenter.com/datacenter1/cluster1/hostsystem1 This allows to omit the HostSystem part in case cluster1 has DRS enabled. Migration is a complex topic, I decided to solve it with a later patch and to do the simple things first :)
[...]
@@ -2173,6 +2283,7 @@ esxDomainDumpXML(virDomainPtr domain, int flags) }
esxVI_String_Free(&propertyNameList); + esxVI_ObjectContent_Free(&datacenter); esxVI_ObjectContent_Free(&virtualMachine); VIR_FREE(datastoreName); VIR_FREE(directoryName);
I'm a bit suspicious, I see no virFree(datacenterName) here ... normal ?
Yes, it's obtained via esxVI_GetStringValue from the datacenter object. The datacenter object owns the string and the string will be freed when the datacenter object gets freed via esxVI_ObjectContent_Free(&datacenter).
Okay, overall a very large part of the patch is the change from priv->host to priv->primary, and there is still some TODOs without an error, I assume they will get fixed soon,
The "TODOs without an error" are the places where I decided to solve the complexer parts in a separate patch later and to do the simple things first.
based on this and after double checking the few points I raised, ACK :-)
thanks !
Daniel
Thanks, pushed. Matthias

On Sat, Jul 24, 2010 at 09:39:31PM +0200, Matthias Bolte wrote:
2010/7/19 Daniel Veillard <veillard@redhat.com>:
On Mon, Jul 19, 2010 at 01:26:10AM +0200, Matthias Bolte wrote:
@@ -49,9 +51,9 @@ esx://example.com/?no_verify=1 (ESX over HTTPS, but doesn't verify the serve type://[username@]hostname[:port]/[?extraparameters]
May I suggest a small extra sentence here, explaining how to compose extraparameters ? User may find from lookuing above that they need to use:
arg=value
but there is no indication on how to separate multiple parameter.
That's true. I'll add a sentence or two about that.
Cool, thanks !
I feel ignorant here. I would assume that a vpx:// connection being to a vCenter vould allow to migrate, care to explain :-) ?
It will, but migration is tricky. Some more details first:
An ESX server has one Datacenter, this Datacenter contains one ComputeResource and this ComputeResource has a single HostSystem attached. Migration is performed between HostSystems in general. Given two ESX connections the driver can easily determine the two involved HostSystems.
A vCenter server can have multiple Datacenters, each Datacenter can contain multiple ComputeResources. There also might by a special type of ComputeResources, the ClusterComputeResource. A ClusterComputeResource may have multiple HostSystems attached. To make it more complex there is DRS. If DRS is enabled for a ClusterComputeResource then the vCenter server will automatically control the VirtualMachine to HostSystem mapping. In that case you can migrate between ClusterComputeResources and the vCenter will select the destination HostSystem for you.
But with the current vpx:// URI you specify the vCenter only, you don't specify the Datacenter or the ComputeResource or the HostSystem yet. Therefore, migration using a vpx:// URI doesn't work yet and I simply short-circuited the VMotion check for a vpx:// connection for now, effectively disabling migration for vpx:// connections.
I plan to model the Datacenter/ComputeResource/HostSystem selection via the path part of the URI: vpx://example-vcenter.com/datacenter1/cluster1/hostsystem1
This allows to omit the HostSystem part in case cluster1 has DRS enabled.
Migration is a complex topic, I decided to solve it with a later patch and to do the simple things first :)
Okay, I didn't expect that level of complexity, but that's normal, we are reaching the limits of teh libvirt level, not talking just to an hypervisor but to a management system, with the DRS implementing user policies instead of the app managing the software. Maybe we could extend virDomainMigrateToURI() to allow a NULL URI in such case where migration target can be decided by the hypervisor. But that would have to be exported in the capabilities first.
[...]
@@ -2173,6 +2283,7 @@ esxDomainDumpXML(virDomainPtr domain, int flags) }
esxVI_String_Free(&propertyNameList); + esxVI_ObjectContent_Free(&datacenter); esxVI_ObjectContent_Free(&virtualMachine); VIR_FREE(datastoreName); VIR_FREE(directoryName);
I'm a bit suspicious, I see no virFree(datacenterName) here ... normal ?
Yes, it's obtained via esxVI_GetStringValue from the datacenter object. The datacenter object owns the string and the string will be freed when the datacenter object gets freed via esxVI_ObjectContent_Free(&datacenter).
okay
Okay, overall a very large part of the patch is the change from priv->host to priv->primary, and there is still some TODOs without an error, I assume they will get fixed soon,
The "TODOs without an error" are the places where I decided to solve the complexer parts in a separate patch later and to do the simple things first.
okay, understood, thanks ! Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

On Mon, Jul 19, 2010 at 01:26:10AM +0200, Matthias Bolte wrote:
Add a pointer to the primary context of a connection and use it in all driver functions that don't dependent on the context type. This includes almost all functions that deal with a virDomianPtr. Therefore, using a vpx:// connection allows you to perform all the usual domain related actions like start, destroy, suspend, resume, dumpxml etc.
Some functions that require an explicitly specified ESX server don't work yet. This includes the host UUID, the hostname, the general node info, the max vCPU count and the free memory. Also not working yet are migration and defining new domains.
If you're connecting to vpx://example-vcenter.com how does the driver know which host you're asking for data on ? IIUC a vcenter reports on all hosts in a data center. Does new mode still guarentee that every domain has a unique name & ID, as well as UUID ? Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://deltacloud.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

2010/7/26 Daniel P. Berrange <berrange@redhat.com>:
On Mon, Jul 19, 2010 at 01:26:10AM +0200, Matthias Bolte wrote:
Add a pointer to the primary context of a connection and use it in all driver functions that don't dependent on the context type. This includes almost all functions that deal with a virDomianPtr. Therefore, using a vpx:// connection allows you to perform all the usual domain related actions like start, destroy, suspend, resume, dumpxml etc.
Some functions that require an explicitly specified ESX server don't work yet. This includes the host UUID, the hostname, the general node info, the max vCPU count and the free memory. Also not working yet are migration and defining new domains.
If you're connecting to vpx://example-vcenter.com how does the driver know which host you're asking for data on ? IIUC a vcenter reports on all hosts in a data center. Does new mode still guarentee that every domain has a unique name & ID, as well as UUID ?
UUID is unique by definition. The driver parses the ID from the internal object name. As far as I understand the object model this ID is unique. But the ID might be different if you look at the same guest through a esx:// or vpx:// connection, but it's unique per connection. The name is a bit more tricky. For a single ESX server it's unique. I thought for a vCenter it's unique per datacenter, because the vCenter won't let you define a second guest with an existing name. I just played a bit with it and it seems there are ways to define two domains with the same name in a single cluster. This is definitely a problem and I'm not sure how to fix that, other than using hacks like adding the ID to the name. In order to have a guaranteed unique domain name for a vpx:// connection the final name will probably have to be build like this <datacenter-name>/<cluster-name>/<domain-name>-<domain-id> Quite ugly and unstable, because it'll change across a migration :( The same name uniqueness problem exists for datastores, because their names are unique per datacenter only. Matthias

2010/7/27 Matthias Bolte <matthias.bolte@googlemail.com>:
2010/7/26 Daniel P. Berrange <berrange@redhat.com>:
On Mon, Jul 19, 2010 at 01:26:10AM +0200, Matthias Bolte wrote:
Add a pointer to the primary context of a connection and use it in all driver functions that don't dependent on the context type. This includes almost all functions that deal with a virDomianPtr. Therefore, using a vpx:// connection allows you to perform all the usual domain related actions like start, destroy, suspend, resume, dumpxml etc.
Some functions that require an explicitly specified ESX server don't work yet. This includes the host UUID, the hostname, the general node info, the max vCPU count and the free memory. Also not working yet are migration and defining new domains.
If you're connecting to vpx://example-vcenter.com how does the driver know which host you're asking for data on ? IIUC a vcenter reports on all hosts in a data center. Does new mode still guarentee that every domain has a unique name & ID, as well as UUID ?
UUID is unique by definition.
The driver parses the ID from the internal object name. As far as I understand the object model this ID is unique. But the ID might be different if you look at the same guest through a esx:// or vpx:// connection, but it's unique per connection.
The name is a bit more tricky. For a single ESX server it's unique. I thought for a vCenter it's unique per datacenter, because the vCenter won't let you define a second guest with an existing name. I just played a bit with it and it seems there are ways to define two domains with the same name in a single cluster. This is definitely a problem and I'm not sure how to fix that, other than using hacks like adding the ID to the name.
In order to have a guaranteed unique domain name for a vpx:// connection the final name will probably have to be build like this
<datacenter-name>/<cluster-name>/<domain-name>-<domain-id>
Actually adding the domain ID should be enough <domain-name>-<domain-id>
Quite ugly and unstable, because it'll change across a migration :(
The same name uniqueness problem exists for datastores, because their names are unique per datacenter only.
Matthias

On Tue, Jul 27, 2010 at 08:39:50PM +0200, Matthias Bolte wrote:
2010/7/26 Daniel P. Berrange <berrange@redhat.com>:
On Mon, Jul 19, 2010 at 01:26:10AM +0200, Matthias Bolte wrote:
Add a pointer to the primary context of a connection and use it in all driver functions that don't dependent on the context type. This includes almost all functions that deal with a virDomianPtr. Therefore, using a vpx:// connection allows you to perform all the usual domain related actions like start, destroy, suspend, resume, dumpxml etc.
Some functions that require an explicitly specified ESX server don't work yet. This includes the host UUID, the hostname, the general node info, the max vCPU count and the free memory. Also not working yet are migration and defining new domains.
If you're connecting to vpx://example-vcenter.com how does the driver know which host you're asking for data on ? IIUC a vcenter reports on all hosts in a data center. Does new mode still guarentee that every domain has a unique name & ID, as well as UUID ?
UUID is unique by definition.
The driver parses the ID from the internal object name. As far as I understand the object model this ID is unique. But the ID might be different if you look at the same guest through a esx:// or vpx:// connection, but it's unique per connection.
The name is a bit more tricky. For a single ESX server it's unique. I thought for a vCenter it's unique per datacenter, because the vCenter won't let you define a second guest with an existing name. I just played a bit with it and it seems there are ways to define two domains with the same name in a single cluster. This is definitely a problem and I'm not sure how to fix that, other than using hacks like adding the ID to the name.
In order to have a guaranteed unique domain name for a vpx:// connection the final name will probably have to be build like this
<datacenter-name>/<cluster-name>/<domain-name>-<domain-id>
Quite ugly and unstable, because it'll change across a migration :(
The same name uniqueness problem exists for datastores, because their names are unique per datacenter only.
I guess what I'm getting at this is that libvirt is really providing a per-host level view of virt. When using vCenter I was expecting that it was still scoped to the host. ie just using vCenter as a means to control an individual host, not using vCenter for controlling all hosts at once. If we go for the latter we're turning libvirt into something more like DeltaCloud which I'm not convinced we want todo Regards, Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://deltacloud.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

2010/7/28 Daniel P. Berrange <berrange@redhat.com>:
On Tue, Jul 27, 2010 at 08:39:50PM +0200, Matthias Bolte wrote:
2010/7/26 Daniel P. Berrange <berrange@redhat.com>:
On Mon, Jul 19, 2010 at 01:26:10AM +0200, Matthias Bolte wrote:
Add a pointer to the primary context of a connection and use it in all driver functions that don't dependent on the context type. This includes almost all functions that deal with a virDomianPtr. Therefore, using a vpx:// connection allows you to perform all the usual domain related actions like start, destroy, suspend, resume, dumpxml etc.
Some functions that require an explicitly specified ESX server don't work yet. This includes the host UUID, the hostname, the general node info, the max vCPU count and the free memory. Also not working yet are migration and defining new domains.
If you're connecting to vpx://example-vcenter.com how does the driver know which host you're asking for data on ? IIUC a vcenter reports on all hosts in a data center. Does new mode still guarentee that every domain has a unique name & ID, as well as UUID ?
UUID is unique by definition.
The driver parses the ID from the internal object name. As far as I understand the object model this ID is unique. But the ID might be different if you look at the same guest through a esx:// or vpx:// connection, but it's unique per connection.
The name is a bit more tricky. For a single ESX server it's unique. I thought for a vCenter it's unique per datacenter, because the vCenter won't let you define a second guest with an existing name. I just played a bit with it and it seems there are ways to define two domains with the same name in a single cluster. This is definitely a problem and I'm not sure how to fix that, other than using hacks like adding the ID to the name.
In order to have a guaranteed unique domain name for a vpx:// connection the final name will probably have to be build like this
<datacenter-name>/<cluster-name>/<domain-name>-<domain-id>
Quite ugly and unstable, because it'll change across a migration :(
The same name uniqueness problem exists for datastores, because their names are unique per datacenter only.
I guess what I'm getting at this is that libvirt is really providing a per-host level view of virt. When using vCenter I was expecting that it was still scoped to the host. ie just using vCenter as a means to control an individual host, not using vCenter for controlling all hosts at once. If we go for the latter we're turning libvirt into something more like DeltaCloud which I'm not convinced we want todo
Regards, Daniel
I think you're right, a vpx:// connection that covers a whole vCenter is probably out of libvirt's scope and gives much trouble with stuff like name uniqueness etc. I'm going to restrict a vpx:// connection to a single host for now: vpx://example-vcenter.com/datacenter1/cluster1/hostsystem1 This solves all name uniqueness issues and it allows to resolve remaining no-host-for-vpx-connection-todos in the driver. This way we don't have a feature in 0.8.3 that might need to be restricted in later version. Once we have a single-host-vpx-connection I'd like to investigate if it's feasible to relax the restrictions on a vpx:// in a way that allows to manage a single cluster too. Internally the driver would always manage (Cluster-)ComputeResources then. The URI for such a connection would omit the host part: vpx://example-vcenter.com/datacenter1/cluster1 Matthias

On Wed, Jul 28, 2010 at 03:22:50PM +0200, Matthias Bolte wrote:
I think you're right, a vpx:// connection that covers a whole vCenter is probably out of libvirt's scope and gives much trouble with stuff like name uniqueness etc.
I'm going to restrict a vpx:// connection to a single host for now:
vpx://example-vcenter.com/datacenter1/cluster1/hostsystem1
This solves all name uniqueness issues and it allows to resolve remaining no-host-for-vpx-connection-todos in the driver. This way we don't have a feature in 0.8.3 that might need to be restricted in later version.
Once we have a single-host-vpx-connection I'd like to investigate if it's feasible to relax the restrictions on a vpx:// in a way that allows to manage a single cluster too. Internally the driver would always manage (Cluster-)ComputeResources then. The URI for such a connection would omit the host part:
vpx://example-vcenter.com/datacenter1/cluster1
This all sounds like a good plan to me Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://deltacloud.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
participants (3)
-
Daniel P. Berrange
-
Daniel Veillard
-
Matthias Bolte