Extend the ESX URL to habdle ports and GSX

* src/esx/esx_driver.c src/esx/esx_vi.[ch] src/esx/esx_vmx.[ch]:
  adds version checking for GSX 2.0, allows to pass a specific port
  for the connection and also add a new specific gsx scheme for
  easier connections to GSX hosts
This commit is contained in:
Matthias Bolte 2009-08-05 10:23:59 +02:00 committed by Daniel Veillard
parent 8feb499ba2
commit 10a4e969a6
5 changed files with 144 additions and 36 deletions

View File

@ -67,16 +67,23 @@ typedef struct _esxPrivate {
/*
* URI format: esx://[<user>@]<server>[?transport={http|https}][&vcenter=<vcenter>][&no_verify={0|1}]
* URI format: {esx|gsx}://[<user>@]<server>[:<port>][?transport={http|https}][&vcenter=<vcenter>][&no_verify={0|1}]
* esx:///phantom
*
* If no port is specified the default port is set dependent on the scheme and
* transport parameter:
* - esx+http 80
* - esx+https 433
* - gsx+http 8222
* - gsx+https 8333
*
* If no transport parameter is specified https is used.
*
* The vcenter parameter is only necessary for migration, because the vCenter
* server is in charge to initiate a migration between two ESX hosts.
*
* If the no_verify parameter is set to 1, this disables libcurl client checks
* of the server's certificate.
* of the server's certificate. The default value it 0.
*
* The esx:///phantom URI may be used for tasks that don't require an actual
* connection to the hypervisor like domxml-{from,to}-native:
@ -95,9 +102,10 @@ esxOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED)
char *password = NULL;
int phantom = 0; // boolean
/* Decline if the URI is NULL or the scheme is not 'esx' */
/* Decline if the URI is NULL or the scheme is neither 'esx' nor 'gsx' */
if (conn->uri == NULL || conn->uri->scheme == NULL ||
STRNEQ(conn->uri->scheme, "esx")) {
(STRCASENEQ(conn->uri->scheme, "esx") &&
STRCASENEQ(conn->uri->scheme, "gsx"))) {
return VIR_DRV_OPEN_DECLINED;
}
@ -147,8 +155,30 @@ esxOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED)
goto failure;
}
if (virAsprintf(&url, "%s://%s/sdk", priv->transport,
conn->uri->server) < 0) {
/*
* Set the port dependent on the transport protocol if no port is
* specified. This allows us to rely on the port parameter being
* correctly set when building URIs later on, without the need to
* distinguish between the situations port == 0 and port != 0
*/
if (conn->uri->port == 0) {
if (STRCASEEQ(conn->uri->scheme, "esx")) {
if (STRCASEEQ(priv->transport, "https")) {
conn->uri->port = 443;
} else {
conn->uri->port = 80;
}
} else { /* GSX */
if (STRCASEEQ(priv->transport, "https")) {
conn->uri->port = 8333;
} else {
conn->uri->port = 8222;
}
}
}
if (virAsprintf(&url, "%s://%s:%d/sdk", priv->transport,
conn->uri->server, conn->uri->port) < 0) {
virReportOOMError(conn);
goto failure;
}
@ -185,6 +215,22 @@ esxOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED)
goto failure;
}
if (STRCASEEQ(conn->uri->scheme, "esx")) {
if (priv->host->productVersion != esxVI_ProductVersion_ESX35 &&
priv->host->productVersion != esxVI_ProductVersion_ESX40) {
ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
"%s is neither an ESX 3.5 host nor an ESX 4.0 host",
conn->uri->server);
goto failure;
}
} else { /* GSX */
if (priv->host->productVersion != esxVI_ProductVersion_GSX20) {
ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
"%s isn't a GSX 2.0 host", conn->uri->server);
goto failure;
}
}
VIR_FREE(url);
VIR_FREE(password);
VIR_FREE(username);
@ -221,6 +267,15 @@ esxOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED)
goto failure;
}
if (priv->vcenter->productVersion != esxVI_ProductVersion_VPX25 &&
priv->vcenter->productVersion != esxVI_ProductVersion_VPX40) {
ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
"%s is neither a vCenter 2.5 server nor a vCenter "
"4.0 server",
conn->uri->server);
goto failure;
}
VIR_FREE(url);
VIR_FREE(password);
VIR_FREE(username);
@ -1996,10 +2051,10 @@ esxDomainDumpXML(virDomainPtr domain, int flags)
goto failure;
}
if (virAsprintf(&url, "%s://%s/folder/%s?dcPath=%s&dsName=%s",
if (virAsprintf(&url, "%s://%s:%d/folder/%s?dcPath=%s&dsName=%s",
priv->transport, domain->conn->uri->server,
vmxPath, priv->host->datacenter->value,
datastoreName) < 0) {
domain->conn->uri->port, vmxPath,
priv->host->datacenter->value, datastoreName) < 0) {
virReportOOMError(domain->conn);
goto failure;
}
@ -2008,7 +2063,7 @@ esxDomainDumpXML(virDomainPtr domain, int flags)
goto failure;
}
def = esxVMX_ParseConfig(domain->conn, vmx, priv->host->serverVersion);
def = esxVMX_ParseConfig(domain->conn, vmx, priv->host->apiVersion);
if (def != NULL) {
xml = virDomainDefFormat(domain->conn, def, flags);
@ -2039,7 +2094,7 @@ esxDomainXMLFromNative(virConnectPtr conn, const char *nativeFormat,
unsigned int flags ATTRIBUTE_UNUSED)
{
esxPrivate *priv = (esxPrivate *)conn->privateData;
int serverVersion = -1;
esxVI_APIVersion apiVersion = esxVI_APIVersion_Unknown;
virDomainDefPtr def = NULL;
char *xml = NULL;
@ -2050,10 +2105,10 @@ esxDomainXMLFromNative(virConnectPtr conn, const char *nativeFormat,
}
if (! priv->phantom) {
serverVersion = priv->host->serverVersion;
apiVersion = priv->host->apiVersion;
}
def = esxVMX_ParseConfig(conn, nativeConfig, serverVersion);
def = esxVMX_ParseConfig(conn, nativeConfig, apiVersion);
if (def != NULL) {
xml = virDomainDefFormat(conn, def, VIR_DOMAIN_XML_INACTIVE);
@ -2581,8 +2636,8 @@ esxDomainMigratePrepare(virConnectPtr dconn,
return -1;
}
if (virAsprintf(uri_out, "%s://%s/sdk", transport,
dconn->uri->server) < 0) {
if (virAsprintf(uri_out, "%s://%s:%d/sdk", transport,
dconn->uri->server, dconn->uri->port) < 0) {
virReportOOMError(dconn);
goto failure;
}

View File

@ -270,9 +270,9 @@ esxVI_Context_Connect(virConnectPtr conn, esxVI_Context *ctx, const char *url,
if (STREQ(ctx->service->about->apiType, "HostAgent") ||
STREQ(ctx->service->about->apiType, "VirtualCenter")) {
if (STRPREFIX(ctx->service->about->apiVersion, "2.5")) {
ctx->apiVersion = 25;
ctx->apiVersion = esxVI_APIVersion_25;
} else if (STRPREFIX(ctx->service->about->apiVersion, "4.0")) {
ctx->apiVersion = 40;
ctx->apiVersion = esxVI_APIVersion_40;
} else {
ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
"Expecting VI API major/minor version '2.5' or '4.0' "
@ -280,14 +280,44 @@ esxVI_Context_Connect(virConnectPtr conn, esxVI_Context *ctx, const char *url,
goto failure;
}
if (STRPREFIX(ctx->service->about->version, "3.5")) {
ctx->serverVersion = 35;
} else if (STRPREFIX(ctx->service->about->version, "4.0")) {
ctx->serverVersion = 40;
if (STREQ(ctx->service->about->productLineId, "gsx")) {
if (STRPREFIX(ctx->service->about->version, "2.0")) {
ctx->productVersion = esxVI_ProductVersion_GSX20;
} else {
ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
"Expecting GSX major/minor version '2.0' but "
"found '%s'", ctx->service->about->version);
goto failure;
}
} else if (STREQ(ctx->service->about->productLineId, "esx") ||
STREQ(ctx->service->about->productLineId, "embeddedEsx")) {
if (STRPREFIX(ctx->service->about->version, "3.5")) {
ctx->productVersion = esxVI_ProductVersion_ESX35;
} else if (STRPREFIX(ctx->service->about->version, "4.0")) {
ctx->productVersion = esxVI_ProductVersion_ESX40;
} else {
ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
"Expecting ESX major/minor version '3.5' or "
"'4.0' but found '%s'",
ctx->service->about->version);
goto failure;
}
} else if (STREQ(ctx->service->about->productLineId, "vpx")) {
if (STRPREFIX(ctx->service->about->version, "2.5")) {
ctx->productVersion = esxVI_ProductVersion_VPX25;
} else if (STRPREFIX(ctx->service->about->version, "4.0")) {
ctx->productVersion = esxVI_ProductVersion_VPX40;
} else {
ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
"Expecting VPX major/minor version '2.5' or '4.0' "
"but found '%s'", ctx->service->about->version);
goto failure;
}
} else {
ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
"Expecting server major/minor version '3.5' or '4.0' "
"but found '%s'", ctx->service->about->version);
"Expecting product 'gsx' or 'esx' or 'embeddedEsx' "
"or 'vpx' but found '%s'",
ctx->service->about->productLineId);
goto failure;
}
} else {

View File

@ -31,6 +31,8 @@
#include "datatypes.h"
#include "esx_vi_types.h"
typedef enum _esxVI_APIVersion esxVI_APIVersion;
typedef enum _esxVI_ProductVersion esxVI_ProductVersion;
typedef struct _esxVI_Context esxVI_Context;
typedef struct _esxVI_RemoteResponse esxVI_RemoteResponse;
typedef struct _esxVI_RemoteRequest esxVI_RemoteRequest;
@ -40,6 +42,24 @@ typedef struct _esxVI_List esxVI_List;
enum _esxVI_APIVersion {
esxVI_APIVersion_Undefined = 0,
esxVI_APIVersion_Unknown,
esxVI_APIVersion_25,
esxVI_APIVersion_40
};
enum _esxVI_ProductVersion {
esxVI_ProductVersion_Undefined = 0,
esxVI_ProductVersion_GSX20,
esxVI_ProductVersion_ESX35,
esxVI_ProductVersion_ESX40,
esxVI_ProductVersion_VPX25,
esxVI_ProductVersion_VPX40
};
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Context
*/
@ -52,8 +72,8 @@ struct _esxVI_Context {
char *username;
char *password;
esxVI_ServiceContent *service;
int apiVersion;
int serverVersion;
esxVI_APIVersion apiVersion;
esxVI_ProductVersion productVersion;
esxVI_UserSession *session;
esxVI_ManagedObjectReference *datacenter;
esxVI_ManagedObjectReference *vmFolder;

View File

@ -406,7 +406,8 @@ def->parallels[0]...
virDomainDefPtr
esxVMX_ParseConfig(virConnectPtr conn, const char *vmx, int serverVersion)
esxVMX_ParseConfig(virConnectPtr conn, const char *vmx,
esxVI_APIVersion apiVersion)
{
virConfPtr conf = NULL;
virDomainDefPtr def = NULL;
@ -453,28 +454,28 @@ esxVMX_ParseConfig(virConnectPtr conn, const char *vmx, int serverVersion)
goto failure;
}
switch (serverVersion) {
case 35:
switch (apiVersion) {
case esxVI_APIVersion_25:
if (virtualHW_version != 4) {
ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
"Expecting VMX entry 'virtualHW.version' to be 4 for "
"server version 3.5 but found %lld", virtualHW_version);
"VI API version 2.5 but found %lld", virtualHW_version);
goto failure;
}
break;
case 40:
case esxVI_APIVersion_40:
if (virtualHW_version != 7) {
ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
"Expecting VMX entry 'virtualHW.version' to be 7 for "
"server version 4.0 but found %lld", virtualHW_version);
"VI API version 4.0 but found %lld", virtualHW_version);
goto failure;
}
break;
case -1:
case esxVI_APIVersion_Unknown:
if (virtualHW_version != 4 && virtualHW_version != 7) {
ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
"Expecting VMX entry 'virtualHW.version' to be 4 or 7 "
@ -486,8 +487,7 @@ esxVMX_ParseConfig(virConnectPtr conn, const char *vmx, int serverVersion)
default:
ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
"Expecting server version 3.5 or 4.0 but got %d",
serverVersion);
"Expecting VI API version 2.5 or 4.0");
goto failure;
}
@ -1343,6 +1343,7 @@ esxVMX_ParseEthernet(virConnectPtr conn, virConfPtr conf, int controller,
ESX_BUILD_VMX_NAME(generatedAddress);
ESX_BUILD_VMX_NAME(address);
ESX_BUILD_VMX_NAME(virtualDev);
ESX_BUILD_VMX_NAME(vnet);
/* vmx:present */
if (esxUtil_GetConfigBoolean(conn, conf, present_name,

View File

@ -25,13 +25,15 @@
#include "internal.h"
#include "domain_conf.h"
#include "esx_vi.h"
virDomainDefPtr
esxVMX_ParseConfig(virConnectPtr conn, const char *vmx, int serverVersion);
esxVMX_ParseConfig(virConnectPtr conn, const char *vmx,
esxVI_APIVersion apiVersion);
int
esxVMX_ParseSCSIController(virConnectPtr conn, virConfPtr conf,
int controller, int *present, char **virtualDev);
int controller, int *present, char **virtualDev);
char *
esxVMX_IndexToDiskName(virConnectPtr conn, int idx, const char *prefix);