]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
ESX add esxDomainDefineXML()
authorMatthias Bolte <matthias.bolte@googlemail.com>
Wed, 23 Sep 2009 12:52:36 +0000 (14:52 +0200)
committerDaniel Veillard <veillard@redhat.com>
Wed, 23 Sep 2009 13:00:54 +0000 (15:00 +0200)
A given domain XML gets converted to a VMX config, uploaded to the host
and registered as new virtual machine.

* src/esx/esx_driver.c: refactor datastore related path parsing into
  esxUtil_ParseDatastoreRelatedPath()
* src/esx/esx_util.[ch]: add esxUtil_ParseDatastoreRelatedPath()
* src/esx/esx_vi.[ch]: add esxVI_Context_UploadFile(), add datastores to
  the traversal in esxVI_BuildFullTraversalSpecList(), add
  esxVI_LookupDatastoreByName()
* src/esx/esx_vi_methods.[ch]: add esxVI_RegisterVM_Task()
* src/esx/esx_vi_types.c: make some error message more verbose
* src/esx/esx_vmx.[ch]: add esxVMX_AbsolutePathToDatastoreRelatedPath()
  to convert a path into a datastore related path, add esxVMX_ParseFileName()
  to convert from VMX path format to domain XML path format, extend the other
  parsing function to be datastore aware, add esxVMX_FormatFileName() to
  convert from domain XML path format to VMX path format, fix VMX ethernet
  entry formating
* tests/esxutilstest.c: add test for esxUtil_ParseDatastoreRelatedPath()
* tests/vmx2xmldata/*: update domain XML files to use datastore related paths
* tests/xml2vmxdata/*: update domain XML files to use datastore related paths,
  update VMX files to use absolute paths

67 files changed:
src/esx/esx_driver.c
src/esx/esx_util.c
src/esx/esx_util.h
src/esx/esx_vi.c
src/esx/esx_vi.h
src/esx/esx_vi_methods.c
src/esx/esx_vi_methods.h
src/esx/esx_vi_types.c
src/esx/esx_vmx.c
src/esx/esx_vmx.h
tests/esxutilstest.c
tests/vmx2xmldata/vmx2xml-cdrom-ide-file.xml
tests/vmx2xmldata/vmx2xml-cdrom-scsi-file.xml
tests/vmx2xmldata/vmx2xml-esx-in-the-wild-1.xml
tests/vmx2xmldata/vmx2xml-esx-in-the-wild-2.xml
tests/vmx2xmldata/vmx2xml-esx-in-the-wild-3.xml
tests/vmx2xmldata/vmx2xml-esx-in-the-wild-4.xml
tests/vmx2xmldata/vmx2xml-floppy-file.xml
tests/vmx2xmldata/vmx2xml-gsx-in-the-wild-1.xml
tests/vmx2xmldata/vmx2xml-gsx-in-the-wild-2.xml
tests/vmx2xmldata/vmx2xml-gsx-in-the-wild-3.xml
tests/vmx2xmldata/vmx2xml-gsx-in-the-wild-4.xml
tests/vmx2xmldata/vmx2xml-harddisk-ide-file.xml
tests/vmx2xmldata/vmx2xml-harddisk-scsi-file.xml
tests/vmx2xmldata/vmx2xml-parallel-file.xml
tests/vmx2xmldata/vmx2xml-scsi-buslogic.xml
tests/vmx2xmldata/vmx2xml-scsi-writethrough.xml
tests/vmx2xmldata/vmx2xml-serial-file.xml
tests/vmx2xmltest.c
tests/xml2vmxdata/xml2vmx-cdrom-ide-file.vmx
tests/xml2vmxdata/xml2vmx-cdrom-ide-file.xml
tests/xml2vmxdata/xml2vmx-cdrom-scsi-file.vmx
tests/xml2vmxdata/xml2vmx-cdrom-scsi-file.xml
tests/xml2vmxdata/xml2vmx-esx-in-the-wild-1.vmx
tests/xml2vmxdata/xml2vmx-esx-in-the-wild-1.xml
tests/xml2vmxdata/xml2vmx-esx-in-the-wild-2.vmx
tests/xml2vmxdata/xml2vmx-esx-in-the-wild-2.xml
tests/xml2vmxdata/xml2vmx-esx-in-the-wild-3.vmx
tests/xml2vmxdata/xml2vmx-esx-in-the-wild-3.xml
tests/xml2vmxdata/xml2vmx-esx-in-the-wild-4.vmx
tests/xml2vmxdata/xml2vmx-esx-in-the-wild-4.xml
tests/xml2vmxdata/xml2vmx-ethernet-bridged.vmx
tests/xml2vmxdata/xml2vmx-ethernet-custom.vmx
tests/xml2vmxdata/xml2vmx-ethernet-e1000.vmx
tests/xml2vmxdata/xml2vmx-floppy-file.vmx
tests/xml2vmxdata/xml2vmx-floppy-file.xml
tests/xml2vmxdata/xml2vmx-gsx-in-the-wild-1.vmx
tests/xml2vmxdata/xml2vmx-gsx-in-the-wild-1.xml
tests/xml2vmxdata/xml2vmx-gsx-in-the-wild-2.vmx
tests/xml2vmxdata/xml2vmx-gsx-in-the-wild-2.xml
tests/xml2vmxdata/xml2vmx-gsx-in-the-wild-3.vmx
tests/xml2vmxdata/xml2vmx-gsx-in-the-wild-3.xml
tests/xml2vmxdata/xml2vmx-gsx-in-the-wild-4.vmx
tests/xml2vmxdata/xml2vmx-gsx-in-the-wild-4.xml
tests/xml2vmxdata/xml2vmx-harddisk-ide-file.vmx
tests/xml2vmxdata/xml2vmx-harddisk-ide-file.xml
tests/xml2vmxdata/xml2vmx-harddisk-scsi-file.vmx
tests/xml2vmxdata/xml2vmx-harddisk-scsi-file.xml
tests/xml2vmxdata/xml2vmx-parallel-file.vmx
tests/xml2vmxdata/xml2vmx-parallel-file.xml
tests/xml2vmxdata/xml2vmx-scsi-buslogic.vmx
tests/xml2vmxdata/xml2vmx-scsi-buslogic.xml
tests/xml2vmxdata/xml2vmx-scsi-writethrough.vmx
tests/xml2vmxdata/xml2vmx-scsi-writethrough.xml
tests/xml2vmxdata/xml2vmx-serial-file.vmx
tests/xml2vmxdata/xml2vmx-serial-file.xml
tests/xml2vmxtest.c

index b37216f70fa9637e8b3ad839855aac7cdf769075..a6708899ab99401e34c53fb1b98cb669ef835d63 100644 (file)
@@ -2267,7 +2267,8 @@ esxDomainDumpXML(virDomainPtr domain, int flags)
     esxVI_DynamicProperty *dynamicProperty = NULL;
     const char *vmPathName = NULL;
     char *datastoreName = NULL;
-    char *vmxPath = NULL;
+    char *directoryName = NULL;
+    char *fileName = NULL;
     virBuffer buffer = VIR_BUFFER_INITIALIZER;
     char *url = NULL;
     char *vmx = NULL;
@@ -2306,17 +2307,21 @@ esxDomainDumpXML(virDomainPtr domain, int flags)
         }
     }
 
-    /* expected format: "[<datastoreName>] <vmxPath>" */
-    if (sscanf(vmPathName, "[%a[^]%]] %a[^\n]", &datastoreName, &vmxPath) != 2) {
-        ESX_ERROR(domain->conn, VIR_ERR_OPERATION_INVALID,
-                  "'config.files.vmPathName' property '%s' doesn't have "
-                  "expected format '[<datastore>] <vmx>'", vmPathName);
+    if (esxUtil_ParseDatastoreRelatedPath(domain->conn, vmPathName,
+                                          &datastoreName, &directoryName,
+                                          &fileName) < 0) {
         goto failure;
     }
 
     virBufferVSprintf(&buffer, "%s://%s:%d/folder/", priv->transport,
                       domain->conn->uri->server, domain->conn->uri->port);
-    virBufferURIEncodeString(&buffer, vmxPath);
+
+    if (directoryName != NULL) {
+        virBufferURIEncodeString(&buffer, directoryName);
+        virBufferAddChar(&buffer, '/');
+    }
+
+    virBufferURIEncodeString(&buffer, fileName);
     virBufferAddLit(&buffer, "?dcPath=");
     virBufferURIEncodeString(&buffer, priv->host->datacenter->value);
     virBufferAddLit(&buffer, "&dsName=");
@@ -2329,11 +2334,12 @@ esxDomainDumpXML(virDomainPtr domain, int flags)
 
     url = virBufferContentAndReset(&buffer);
 
-    if (esxVI_Context_Download(domain->conn, priv->host, url, &vmx) < 0) {
+    if (esxVI_Context_DownloadFile(domain->conn, priv->host, url, &vmx) < 0) {
         goto failure;
     }
 
-    def = esxVMX_ParseConfig(domain->conn, vmx, priv->host->apiVersion);
+    def = esxVMX_ParseConfig(domain->conn, priv->host, vmx, datastoreName,
+                             directoryName, priv->host->apiVersion);
 
     if (def != NULL) {
         xml = virDomainDefFormat(domain->conn, def, flags);
@@ -2343,7 +2349,8 @@ esxDomainDumpXML(virDomainPtr domain, int flags)
     esxVI_String_Free(&propertyNameList);
     esxVI_ObjectContent_Free(&virtualMachine);
     VIR_FREE(datastoreName);
-    VIR_FREE(vmxPath);
+    VIR_FREE(directoryName);
+    VIR_FREE(fileName);
     VIR_FREE(url);
     VIR_FREE(vmx);
     virDomainDefFree(def);
@@ -2364,6 +2371,7 @@ esxDomainXMLFromNative(virConnectPtr conn, const char *nativeFormat,
                        unsigned int flags ATTRIBUTE_UNUSED)
 {
     esxPrivate *priv = (esxPrivate *)conn->privateData;
+    esxVI_Context *ctx = NULL;
     esxVI_APIVersion apiVersion = esxVI_APIVersion_Unknown;
     virDomainDefPtr def = NULL;
     char *xml = NULL;
@@ -2375,10 +2383,11 @@ esxDomainXMLFromNative(virConnectPtr conn, const char *nativeFormat,
     }
 
     if (! priv->phantom) {
+        ctx = priv->host;
         apiVersion = priv->host->apiVersion;
     }
 
-    def = esxVMX_ParseConfig(conn, nativeConfig, apiVersion);
+    def = esxVMX_ParseConfig(conn, ctx, nativeConfig, "?", "?", apiVersion);
 
     if (def != NULL) {
         xml = virDomainDefFormat(conn, def, VIR_DOMAIN_XML_INACTIVE);
@@ -2418,7 +2427,7 @@ esxDomainXMLToNative(virConnectPtr conn, const char *nativeFormat,
         return NULL;
     }
 
-    vmx = esxVMX_FormatConfig(conn, def, priv->host->apiVersion);
+    vmx = esxVMX_FormatConfig(conn, priv->host, def, priv->host->apiVersion);
 
     virDomainDefFree(def);
 
@@ -2605,6 +2614,195 @@ esxDomainCreate(virDomainPtr domain)
 
 
 
+static virDomainPtr
+esxDomainDefineXML(virConnectPtr conn, const char *xml ATTRIBUTE_UNUSED)
+{
+    esxPrivate *priv = (esxPrivate *)conn->privateData;
+    virDomainDefPtr def = NULL;
+    char *vmx = NULL;
+    esxVI_ObjectContent *virtualMachine = NULL;
+    char *datastoreName = NULL;
+    char *directoryName = NULL;
+    char *fileName = NULL;
+    virBuffer buffer = VIR_BUFFER_INITIALIZER;
+    char *url = NULL;
+    char *datastoreRelatedPath = NULL;
+    esxVI_String *propertyNameList = NULL;
+    esxVI_ObjectContent *hostSystem = NULL;
+    esxVI_ManagedObjectReference *resourcePool = NULL;
+    esxVI_ManagedObjectReference *task = NULL;
+    esxVI_TaskInfoState taskInfoState;
+    virDomainPtr domain = NULL;
+
+    if (priv->phantom) {
+        ESX_ERROR(conn, VIR_ERR_OPERATION_INVALID,
+                  "Not possible with a phantom connection");
+        goto failure;
+    }
+
+    if (esxVI_EnsureSession(conn, priv->host) < 0) {
+        goto failure;
+    }
+
+    /* Parse domain XML */
+    def = virDomainDefParseString(conn, priv->caps, xml,
+                                  VIR_DOMAIN_XML_INACTIVE);
+
+    if (def == NULL) {
+        goto failure;
+    }
+
+    /* Check if an existing domain should be edited */
+    if (esxVI_LookupVirtualMachineByUuid(conn, priv->host, def->uuid, NULL,
+                                         &virtualMachine,
+                                         esxVI_Occurence_OptionalItem) < 0) {
+        goto failure;
+    }
+
+    if (virtualMachine != NULL) {
+        /* FIXME */
+        ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
+                  "Domain already exists, editing existing domains is not "
+                  "supported yet");
+        goto failure;
+    }
+
+    /* Build VMX from domain XML */
+    vmx = esxVMX_FormatConfig(conn, priv->host, def, priv->host->apiVersion);
+
+    if (vmx == NULL) {
+        goto failure;
+    }
+
+    /* Build VMX datastore URL */
+    if (def->ndisks < 1) {
+        ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
+                  "Domain XML doesn't contain a disk, cannot deduce datastore "
+                  "and path for VMX file");
+        goto failure;
+    }
+
+    if (def->disks[0]->src == NULL) {
+        ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
+                  "First disk has no source, cannot deduce datastore and path "
+                  "for VMX file");
+        goto failure;
+    }
+
+    if (esxUtil_ParseDatastoreRelatedPath(conn, def->disks[0]->src,
+                                          &datastoreName, &directoryName,
+                                          &fileName) < 0) {
+        goto failure;
+    }
+
+    if (! esxUtil_EqualSuffix(fileName, ".vmdk")) {
+        ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
+                  "Expecting source of first disk '%s' to be a VMDK image",
+                  def->disks[0]->src);
+        goto failure;
+    }
+
+    virBufferVSprintf(&buffer, "%s://%s:%d/folder/", priv->transport,
+                      conn->uri->server, conn->uri->port);
+
+    if (directoryName != NULL) {
+        virBufferURIEncodeString(&buffer, directoryName);
+        virBufferAddChar(&buffer, '/');
+    }
+
+    virBufferURIEncodeString(&buffer, def->name);
+    virBufferAddLit(&buffer, ".vmx?dcPath=");
+    virBufferURIEncodeString(&buffer, priv->host->datacenter->value);
+    virBufferAddLit(&buffer, "&dsName=");
+    virBufferURIEncodeString(&buffer, datastoreName);
+
+    if (virBufferError(&buffer)) {
+        virReportOOMError(conn);
+        goto failure;
+    }
+
+    url = virBufferContentAndReset(&buffer);
+
+    if (directoryName != NULL) {
+        if (virAsprintf(&datastoreRelatedPath, "[%s] %s/%s.vmx", datastoreName,
+                        directoryName, def->name) < 0) {
+            virReportOOMError(conn);
+            goto failure;
+        }
+    } else {
+        if (virAsprintf(&datastoreRelatedPath, "[%s] %s.vmx", datastoreName,
+                        def->name) < 0) {
+            virReportOOMError(conn);
+            goto failure;
+        }
+    }
+
+    /* Get resource pool */
+    if (esxVI_String_AppendValueToList(conn, &propertyNameList, "parent") < 0 ||
+        esxVI_LookupHostSystemByIp(conn, priv->host, priv->host->ipAddress,
+                                   propertyNameList, &hostSystem) < 0) {
+        goto failure;
+    }
+
+    if (esxVI_GetResourcePool(conn, priv->host, hostSystem,
+                              &resourcePool) < 0) {
+        goto failure;
+    }
+
+    /* Check, if VMX file already exists */
+    /* FIXME */
+
+    /* Upload VMX file */
+    if (esxVI_Context_UploadFile(conn, priv->host, url, vmx) < 0) {
+        goto failure;
+    }
+
+    /* Register the domain */
+    if (esxVI_RegisterVM_Task(conn, priv->host, priv->host->vmFolder,
+                              datastoreRelatedPath, NULL, esxVI_Boolean_False,
+                              resourcePool, hostSystem->obj, &task) < 0 ||
+        esxVI_WaitForTaskCompletion(conn, priv->host, task,
+                                    &taskInfoState) < 0) {
+        goto failure;
+    }
+
+    if (taskInfoState != esxVI_TaskInfoState_Success) {
+        ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR, "Could not define domain");
+        goto failure;
+    }
+
+    domain = virGetDomain(conn, def->name, def->uuid);
+
+    if (domain != NULL) {
+        domain->id = -1;
+    }
+
+    /* FIXME: Add proper rollback in case of an error */
+
+  cleanup:
+    virDomainDefFree(def);
+    VIR_FREE(vmx);
+    VIR_FREE(datastoreName);
+    VIR_FREE(directoryName);
+    VIR_FREE(fileName);
+    VIR_FREE(url);
+    VIR_FREE(datastoreRelatedPath);
+    esxVI_ObjectContent_Free(&virtualMachine);
+    esxVI_String_Free(&propertyNameList);
+    esxVI_ObjectContent_Free(&hostSystem);
+    esxVI_ManagedObjectReference_Free(&resourcePool);
+    esxVI_ManagedObjectReference_Free(&task);
+
+    return domain;
+
+  failure:
+    domain = NULL;
+
+    goto cleanup;
+}
+
+
+
 static int
 esxDomainUndefine(virDomainPtr domain)
 {
@@ -3297,7 +3495,7 @@ static virDriver esxDriver = {
     esxListDefinedDomains,           /* listDefinedDomains */
     esxNumberOfDefinedDomains,       /* numOfDefinedDomains */
     esxDomainCreate,                 /* domainCreate */
-    NULL,                            /* domainDefineXML */
+    esxDomainDefineXML,              /* domainDefineXML */
     esxDomainUndefine,               /* domainUndefine */
     NULL,                            /* domainAttachDevice */
     NULL,                            /* domainDetachDevice */
index 7130a415005f53b6c5a74febf7d9bf4b2805938a..67bbcb8b68fa63e9fbcd324e851f0ff221f6aed5 100644 (file)
@@ -263,6 +263,89 @@ esxUtil_ParseVirtualMachineIDString(const char *id_string, int *id)
 
 
 
+int
+esxUtil_ParseDatastoreRelatedPath(virConnectPtr conn,
+                                  const char *datastoreRelatedPath,
+                                  char **datastoreName,
+                                  char **directoryName, char **fileName)
+{
+    int result = 0;
+    char *directoryAndFileName = NULL;
+    char *separator = NULL;
+
+    if (datastoreName == NULL || *datastoreName != NULL ||
+        directoryName == NULL || *directoryName != NULL ||
+        fileName == NULL || *fileName != NULL) {
+        ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR, "Invalid argument");
+        goto failure;
+    }
+
+    /*
+     * Parse string as '[<datastore>] <path>'. '%as' is similar to '%s', but
+     * sscanf() will allocate the memory for the string, so the caller doesn't
+     * need to preallocate a buffer that's large enough.
+     *
+     * The s in '%as' can be replaced with a character set, e.g. [a-z].
+     *
+     * '%a[^]%]' matches <datastore>. '[^]%]' excludes ']' from the accepted
+     * characters, otherwise sscanf() wont match what it should.
+     *
+     * '%a[^\n]' matches <path>. '[^\n]' excludes '\n' from the accepted
+     * characters, otherwise sscanf() would only match up to the first space,
+     * but spaces are valid in <path>.
+     */
+    if (sscanf(datastoreRelatedPath, "[%a[^]%]] %a[^\n]", datastoreName,
+               &directoryAndFileName) != 2) {
+        ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
+                  "Datastore related path '%s' doesn't have expected format "
+                  "'[<datastore>] <path>'", datastoreRelatedPath);
+        goto failure;
+    }
+
+    /* Split <path> into <directory>/<file>, where <directory> is optional */
+    separator = strrchr(directoryAndFileName, '/');
+
+    if (separator != NULL) {
+        *separator++ = '\0';
+
+        *directoryName = directoryAndFileName;
+        directoryAndFileName = NULL;
+
+        if (*separator == '\0') {
+            ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
+                      "Datastore related path '%s' doesn't reference a file",
+                      datastoreRelatedPath);
+            goto failure;
+        }
+
+        *fileName = strdup(separator);
+
+        if (*fileName == NULL) {
+            virReportOOMError(conn);
+            goto failure;
+        }
+    } else {
+        *fileName = directoryAndFileName;
+        directoryAndFileName = NULL;
+    }
+
+  cleanup:
+    VIR_FREE(directoryAndFileName);
+
+    return result;
+
+  failure:
+    VIR_FREE(*datastoreName);
+    VIR_FREE(*directoryName);
+    VIR_FREE(*fileName);
+
+    result = -1;
+
+    goto cleanup;
+}
+
+
+
 int
 esxUtil_ResolveHostname(virConnectPtr conn, const char *hostname,
                         char *ipAddress, size_t ipAddress_length)
index e4922c16ad9dd5a640ff68813b67999950763efa..8e3f039e80079781779350468479b83259ecc560 100644 (file)
@@ -40,6 +40,11 @@ int esxUtil_ParseQuery(virConnectPtr conn, char **transport, char **vCenter,
 
 int esxUtil_ParseVirtualMachineIDString(const char *id_string, int *id);
 
+int esxUtil_ParseDatastoreRelatedPath(virConnectPtr conn,
+                                      const char *datastoreRelatedPath,
+                                      char **datastoreName,
+                                      char **directoryName, char **fileName);
+
 int esxUtil_ResolveHostname(virConnectPtr conn, const char *hostname,
                             char *ipAddress, size_t ipAddress_length);
 
index 0a531cbe2bea244f953cbe892cbe5e8334089478..6cc23498a885361c8b66b50618cc0b915d4fc5ee 100644 (file)
@@ -138,7 +138,35 @@ ESX_VI__TEMPLATE__FREE(Context,
 });
 
 static size_t
-_esxVI_CURL_WriteBuffer(char *data, size_t size, size_t nmemb, void *buffer)
+esxVI_CURL_ReadString(char *data, size_t size, size_t nmemb, void *ptrptr)
+{
+    const char *content = *(const char **)ptrptr;
+    size_t available = 0;
+    size_t requested = size * nmemb;
+
+    if (content == NULL) {
+        return 0;
+    }
+
+    available = strlen(content);
+
+    if (available == 0) {
+        return 0;
+    }
+
+    if (requested > available) {
+        requested = available;
+    }
+
+    memcpy(data, content, requested);
+
+    *(const char **)ptrptr = content + requested;
+
+    return requested;
+}
+
+static size_t
+esxVI_CURL_WriteBuffer(char *data, size_t size, size_t nmemb, void *buffer)
 {
     if (buffer != NULL) {
         virBufferAdd((virBufferPtr) buffer, data, size * nmemb);
@@ -153,8 +181,8 @@ _esxVI_CURL_WriteBuffer(char *data, size_t size, size_t nmemb, void *buffer)
 
 #if ESX_VI__CURL__ENABLE_DEBUG_OUTPUT
 static int
-_esxVI_CURL_Debug(CURL *curl ATTRIBUTE_UNUSED, curl_infotype type,
-                  char *info, size_t size, void *data ATTRIBUTE_UNUSED)
+esxVI_CURL_Debug(CURL *curl ATTRIBUTE_UNUSED, curl_infotype type,
+                 char *info, size_t size, void *data ATTRIBUTE_UNUSED)
 {
     switch (type) {
       case CURLINFO_TEXT:
@@ -246,11 +274,13 @@ esxVI_Context_Connect(virConnectPtr conn, esxVI_Context *ctx, const char *url,
     curl_easy_setopt(ctx->curl_handle, CURLOPT_SSL_VERIFYHOST, noVerify ? 0 : 2);
     curl_easy_setopt(ctx->curl_handle, CURLOPT_COOKIEFILE, "");
     curl_easy_setopt(ctx->curl_handle, CURLOPT_HTTPHEADER, ctx->curl_headers);
+    curl_easy_setopt(ctx->curl_handle, CURLOPT_READFUNCTION,
+                     esxVI_CURL_ReadString);
     curl_easy_setopt(ctx->curl_handle, CURLOPT_WRITEFUNCTION,
-                     _esxVI_CURL_WriteBuffer);
+                     esxVI_CURL_WriteBuffer);
 #if ESX_VI__CURL__ENABLE_DEBUG_OUTPUT
     curl_easy_setopt(ctx->curl_handle, CURLOPT_DEBUGFUNCTION,
-                     _esxVI_CURL_Debug);
+                     esxVI_CURL_Debug);
 #endif
 
     if (virMutexInit(&ctx->curl_lock) < 0) {
@@ -398,8 +428,8 @@ esxVI_Context_Connect(virConnectPtr conn, esxVI_Context *ctx, const char *url,
 }
 
 int
-esxVI_Context_Download(virConnectPtr conn, esxVI_Context *ctx, const char *url,
-                       char **content)
+esxVI_Context_DownloadFile(virConnectPtr conn, esxVI_Context *ctx,
+                           const char *url, char **content)
 {
     virBuffer buffer = VIR_BUFFER_INITIALIZER;
     CURLcode errorCode;
@@ -414,6 +444,7 @@ esxVI_Context_Download(virConnectPtr conn, esxVI_Context *ctx, const char *url,
 
     curl_easy_setopt(ctx->curl_handle, CURLOPT_URL, url);
     curl_easy_setopt(ctx->curl_handle, CURLOPT_WRITEDATA, &buffer);
+    curl_easy_setopt(ctx->curl_handle, CURLOPT_UPLOAD, 0);
     curl_easy_setopt(ctx->curl_handle, CURLOPT_HTTPGET, 1);
 
     errorCode = curl_easy_perform(ctx->curl_handle);
@@ -464,6 +495,61 @@ esxVI_Context_Download(virConnectPtr conn, esxVI_Context *ctx, const char *url,
     goto failure;
 }
 
+int
+esxVI_Context_UploadFile(virConnectPtr conn, esxVI_Context *ctx,
+                         const char *url, const char *content)
+{
+    CURLcode errorCode;
+    long responseCode;
+
+    if (content == NULL) {
+        ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR, "Invalid argument");
+        return -1;
+    }
+
+    virMutexLock(&ctx->curl_lock);
+
+    curl_easy_setopt(ctx->curl_handle, CURLOPT_URL, url);
+    curl_easy_setopt(ctx->curl_handle, CURLOPT_READDATA, &content);
+    curl_easy_setopt(ctx->curl_handle, CURLOPT_UPLOAD, 1);
+    curl_easy_setopt(ctx->curl_handle, CURLOPT_INFILESIZE, strlen(content));
+
+    errorCode = curl_easy_perform(ctx->curl_handle);
+
+    if (errorCode != CURLE_OK) {
+        ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
+                     "curl_easy_perform() returned an error: %s (%d)",
+                     curl_easy_strerror(errorCode), errorCode);
+        goto unlock;
+    }
+
+    errorCode = curl_easy_getinfo(ctx->curl_handle, CURLINFO_RESPONSE_CODE,
+                                  &responseCode);
+
+    if (errorCode != CURLE_OK) {
+        ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
+                     "curl_easy_getinfo() returned an error: %s (%d)",
+                     curl_easy_strerror(errorCode), errorCode);
+        goto unlock;
+    }
+
+    virMutexUnlock(&ctx->curl_lock);
+
+    if (responseCode != 200 && responseCode != 201) {
+        ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
+                     "HTTP response code %d while trying to upload to '%s'",
+                     (int)responseCode, url);
+        return -1;
+    }
+
+    return 0;
+
+  unlock:
+    virMutexUnlock(&ctx->curl_lock);
+
+    return -1;
+}
+
 int
 esxVI_Context_Execute(virConnectPtr conn, esxVI_Context *ctx,
                       const char *request, const char *xpathExpression,
@@ -486,6 +572,7 @@ esxVI_Context_Execute(virConnectPtr conn, esxVI_Context *ctx,
 
     curl_easy_setopt(ctx->curl_handle, CURLOPT_URL, ctx->url);
     curl_easy_setopt(ctx->curl_handle, CURLOPT_WRITEDATA, &buffer);
+    curl_easy_setopt(ctx->curl_handle, CURLOPT_UPLOAD, 0);
     curl_easy_setopt(ctx->curl_handle, CURLOPT_POSTFIELDS, request);
     curl_easy_setopt(ctx->curl_handle, CURLOPT_POSTFIELDSIZE, strlen(request));
 
@@ -1085,15 +1172,24 @@ esxVI_BuildFullTraversalSpecList(virConnectPtr conn,
                                          "visitFolders",
                                          "Folder", "childEntity",
                                          "visitFolders\0"
+                                         "datacenterToDatastore\0"
                                          "datacenterToVmFolder\0"
                                          "datacenterToHostFolder\0"
                                          "computeResourceToHost\0"
                                          "computeResourceToResourcePool\0"
-                                         "HostSystemToVm\0"
+                                         "hostSystemToVm\0"
                                          "resourcePoolToVm\0") < 0) {
         goto failure;
     }
 
+    /* Traversal through datastore branch */
+    if (esxVI_BuildFullTraversalSpecItem(conn, fullTraversalSpecList,
+                                         "datacenterToDatastore",
+                                         "Datacenter", "datastore",
+                                         NULL) < 0) {
+        goto failure;
+    }
+
     /* Traversal through vmFolder branch */
     if (esxVI_BuildFullTraversalSpecItem(conn, fullTraversalSpecList,
                                          "datacenterToVmFolder",
@@ -1138,7 +1234,7 @@ esxVI_BuildFullTraversalSpecList(virConnectPtr conn,
 
     /* Recurse through all hosts */
     if (esxVI_BuildFullTraversalSpecItem(conn, fullTraversalSpecList,
-                                         "HostSystemToVm",
+                                         "hostSystemToVm",
                                          "HostSystem", "vm",
                                          "visitFolders\0") < 0) {
         goto failure;
@@ -1351,7 +1447,8 @@ esxVI_GetManagedEntityStatus(virConnectPtr conn,
     }
 
     ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
-                 "Missing '%s' property", propertyName);
+                 "Missing '%s' property while looking for ManagedEntityStatus",
+                 propertyName);
 
     return -1;
 }
@@ -1725,6 +1822,119 @@ esxVI_LookupVirtualMachineByUuid(virConnectPtr conn, esxVI_Context *ctx,
 
 
 
+int
+esxVI_LookupDatastoreByName(virConnectPtr conn, esxVI_Context *ctx,
+                            const char *name, esxVI_String *propertyNameList,
+                            esxVI_ObjectContent **datastore,
+                            esxVI_Occurence occurence)
+{
+    int result = 0;
+    esxVI_String *completePropertyNameList = NULL;
+    esxVI_ObjectContent *datastoreList = NULL;
+    esxVI_ObjectContent *candidate = NULL;
+    esxVI_DynamicProperty *dynamicProperty = NULL;
+    size_t offset = strlen("/vmfs/volumes/");
+
+    if (datastore == NULL || *datastore != NULL) {
+        ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR, "Invalid argument");
+        return -1;
+    }
+
+    /* Get all datastores */
+    if (esxVI_String_DeepCopyList(conn, &completePropertyNameList,
+                                  propertyNameList) < 0 ||
+        esxVI_String_AppendValueListToList(conn, &completePropertyNameList,
+                                           "info.name\0"
+                                           "info.url\0") < 0) {
+        goto failure;
+    }
+
+    if (esxVI_GetObjectContent(conn, ctx, ctx->datacenter,
+                               "Datastore", completePropertyNameList,
+                               esxVI_Boolean_True, &datastoreList) < 0) {
+        goto failure;
+    }
+
+    if (datastoreList == NULL) {
+        if (occurence == esxVI_Occurence_OptionalItem) {
+            goto cleanup;
+        } else {
+            ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
+                         "No datastores available");
+            goto failure;
+        }
+    }
+
+    /* Search for a matching datastore */
+    for (candidate = datastoreList; candidate != NULL;
+         candidate = candidate->_next) {
+        for (dynamicProperty = candidate->propSet; dynamicProperty != NULL;
+             dynamicProperty = dynamicProperty->_next) {
+            if (STREQ(dynamicProperty->name, "info.name")) {
+                if (esxVI_AnyType_ExpectType(conn, dynamicProperty->val,
+                                             esxVI_Type_String) < 0) {
+                    goto failure;
+                }
+
+                if (STREQ(dynamicProperty->val->string, name)) {
+                    if (esxVI_ObjectContent_DeepCopy(conn, datastore,
+                                                     candidate) < 0) {
+                        goto failure;
+                    }
+
+                    /* Found datastore with matching name */
+                    goto cleanup;
+                }
+            } else if (STREQ(dynamicProperty->name, "info.url")) {
+                if (esxVI_AnyType_ExpectType(conn, dynamicProperty->val,
+                                             esxVI_Type_String) < 0) {
+                    goto failure;
+                }
+
+                if (! STRPREFIX(dynamicProperty->val->string,
+                                "/vmfs/volumes/")) {
+                    ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
+                                 "Datastore URL '%s' has unexpected prefix, "
+                                 "expecting '/vmfs/volumes/' prefix",
+                                 dynamicProperty->val->string);
+                    goto failure;
+                }
+
+                if (STREQ(dynamicProperty->val->string + offset, name)) {
+                    if (esxVI_ObjectContent_DeepCopy(conn, datastore,
+                                                     candidate) < 0) {
+                        goto failure;
+                    }
+
+                    /* Found datastore with matching URL suffix */
+                    goto cleanup;
+                }
+            } else {
+                VIR_WARN("Unexpected '%s' property", dynamicProperty->name);
+            }
+        }
+    }
+
+    if (occurence != esxVI_Occurence_OptionalItem) {
+        ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
+                     "Could not find datastore with name '%s'", name);
+        goto failure;
+    }
+
+  cleanup:
+    esxVI_String_Free(&completePropertyNameList);
+    esxVI_ObjectContent_Free(&datastoreList);
+
+    return result;
+
+  failure:
+    result = -1;
+
+    goto cleanup;
+}
+
+
+
 int
 esxVI_StartVirtualMachineTask(virConnectPtr conn, esxVI_Context *ctx,
                               const char *name, const char *request,
index 54fe82e49d2da50dfdff40a5bc92da18b403c73f..6ba6bed25fa83299c9357f06fc883f064ecf92dd 100644 (file)
@@ -95,8 +95,10 @@ int esxVI_Context_Connect(virConnectPtr conn, esxVI_Context *ctx,
                           const char *ipAddress, const char *url,
                           const char *username, const char *password,
                           int noVerify);
-int esxVI_Context_Download(virConnectPtr conn, esxVI_Context *ctx,
-                           const char *url, char **content);
+int esxVI_Context_DownloadFile(virConnectPtr conn, esxVI_Context *ctx,
+                               const char *url, char **content);
+int esxVI_Context_UploadFile(virConnectPtr conn, esxVI_Context *ctx,
+                             const char *url, const char *content);
 int esxVI_Context_Execute(virConnectPtr conn, esxVI_Context *ctx,
                           const char *request, const char *xpathExpression,
                           esxVI_Response **response, esxVI_Boolean expectList);
@@ -246,6 +248,12 @@ int esxVI_LookupVirtualMachineByUuid(virConnectPtr conn, esxVI_Context *ctx,
                                      esxVI_ObjectContent **virtualMachine,
                                      esxVI_Occurence occurence);
 
+int esxVI_LookupDatastoreByName(virConnectPtr conn, esxVI_Context *ctx,
+                                const char *name,
+                                esxVI_String *propertyNameList,
+                                esxVI_ObjectContent **datastore,
+                                esxVI_Occurence occurence);
+
 int esxVI_StartVirtualMachineTask(virConnectPtr conn, esxVI_Context *ctx,
                                   const char *name, const char *request,
                                   esxVI_ManagedObjectReference **task);
index dfcd4a0b0b0354822a1e73a87c95ea988f556f95..a80d1bf7a93496cdebd1d4cd263f5abde0855d06 100644 (file)
@@ -520,6 +520,76 @@ esxVI_ReconfigVM_Task(virConnectPtr conn, esxVI_Context *ctx,
 
 
 
+int
+esxVI_RegisterVM_Task(virConnectPtr conn, esxVI_Context *ctx,
+                      esxVI_ManagedObjectReference *folder,
+                      const char *path, const char *name,
+                      esxVI_Boolean asTemplate,
+                      esxVI_ManagedObjectReference *resourcePool,
+                      esxVI_ManagedObjectReference *hostSystem,
+                      esxVI_ManagedObjectReference **task)
+{
+    int result = 0;
+    virBuffer buffer = VIR_BUFFER_INITIALIZER;
+    char *request = NULL;
+
+    if (task == NULL || *task != NULL) {
+        ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR, "Invalid argument");
+        return -1;
+    }
+
+    virBufferAddLit(&buffer, ESX_VI__SOAP__REQUEST_HEADER);
+    virBufferAddLit(&buffer, "<RegisterVM_Task xmlns=\"urn:vim25\">");
+
+    if (esxVI_ManagedObjectReference_Serialize(conn, folder, "_this", &buffer,
+                                               esxVI_Boolean_True) < 0 ||
+        esxVI_String_SerializeValue(conn, path, "path", &buffer,
+                                    esxVI_Boolean_True) < 0 ||
+        esxVI_String_SerializeValue(conn, name, "name", &buffer,
+                                    esxVI_Boolean_False) < 0 ||
+        esxVI_Boolean_Serialize(conn, asTemplate, "asTemplate", &buffer,
+                                esxVI_Boolean_False) < 0 ||
+        esxVI_ManagedObjectReference_Serialize(conn, resourcePool, "pool",
+                                               &buffer,
+                                               esxVI_Boolean_False) < 0 ||
+        esxVI_ManagedObjectReference_Serialize(conn, hostSystem, "host",
+                                               &buffer,
+                                               esxVI_Boolean_False) < 0) {
+        goto failure;
+    }
+
+    virBufferAddLit(&buffer, "</RegisterVM_Task>");
+    virBufferAddLit(&buffer, ESX_VI__SOAP__REQUEST_FOOTER);
+
+    if (virBufferError(&buffer)) {
+        virReportOOMError(conn);
+        goto failure;
+    }
+
+    request = virBufferContentAndReset(&buffer);
+
+    if (esxVI_StartVirtualMachineTask(conn, ctx, "RegisterVM", request,
+                                      task) < 0) {
+        goto failure;
+    }
+
+  cleanup:
+    VIR_FREE(request);
+
+    return result;
+
+  failure:
+    if (request == NULL) {
+        request = virBufferContentAndReset(&buffer);
+    }
+
+    result = -1;
+
+    goto cleanup;
+}
+
+
+
 int
 esxVI_UnregisterVM(virConnectPtr conn, esxVI_Context *ctx,
                    esxVI_ManagedObjectReference *virtualMachine)
index e63184fe9d37af2f1f7464e9f4aa548979e16dee..5f3caff9c8ad24e0e1bd88b7e4e24ab32e8da3b6 100644 (file)
@@ -72,6 +72,14 @@ int esxVI_ReconfigVM_Task(virConnectPtr conn, esxVI_Context *ctx,
                           esxVI_VirtualMachineConfigSpec *spec,
                           esxVI_ManagedObjectReference **task);
 
+int esxVI_RegisterVM_Task(virConnectPtr conn, esxVI_Context *ctx,
+                          esxVI_ManagedObjectReference *folder,
+                          const char *path, const char *name,
+                          esxVI_Boolean asTemplate,
+                          esxVI_ManagedObjectReference *resourcePool,
+                          esxVI_ManagedObjectReference *hostSystem,
+                          esxVI_ManagedObjectReference **task);
+
 int esxVI_UnregisterVM(virConnectPtr conn, esxVI_Context *ctx,
                        esxVI_ManagedObjectReference *virtualMachine);
 
index d3d306e5ee0e91cca3221a7e789cf6b4ba5b1ff0..73d306929b2c62bf374ffdc8b729e087f20e2178 100644 (file)
@@ -633,7 +633,8 @@ esxVI_AnyType_Deserialize(virConnectPtr conn, xmlNodePtr node,
                  BAD_CAST "http://www.w3.org/2001/XMLSchema-instance");
 
     if ((*anyType)->other == NULL) {
-        ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR, "Missing 'type' property");
+        ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
+                     "AnyType is missing 'type' property");
         goto failure;
     }
 
@@ -1388,7 +1389,8 @@ esxVI_ManagedObjectReference_Deserialize
       (char *)xmlGetNoNsProp(node, BAD_CAST "type");
 
     if ((*managedObjectReference)->type == NULL) {
-        ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR, "Missing 'type' property");
+        ESX_VI_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
+                     "ManagedObjectReference is missing 'type' property");
         goto failure;
     }
 
index dea2a12e482e502161bede6e537c3effa566742e..f2f09e6f5c487eb0f458148de9f4c3075aecaa0c 100644 (file)
@@ -414,8 +414,8 @@ def->parallels[0]...
 #define VIR_FROM_THIS VIR_FROM_ESX
 
 #define ESX_ERROR(conn, code, fmt...)                                         \
-    virReportErrorHelper (conn, VIR_FROM_ESX, code, __FILE__, __FUNCTION__,   \
-                          __LINE__, fmt)
+    virReportErrorHelper(conn, VIR_FROM_ESX, code, __FILE__, __FUNCTION__,    \
+                         __LINE__, fmt)
 
 
 
@@ -583,12 +583,134 @@ esxVMX_GatherSCSIControllers(virConnectPtr conn, virDomainDefPtr def,
 
 
 
+char *
+esxVMX_AbsolutePathToDatastoreRelatedPath(virConnectPtr conn,
+                                          esxVI_Context *ctx,
+                                          const char *absolutePath)
+{
+    char *datastoreRelatedPath = NULL;
+    char *preliminaryDatastoreName = NULL;
+    char *directoryAndFileName = NULL;
+    esxVI_DynamicProperty *dynamicProperty = NULL;
+    esxVI_ObjectContent *datastore = NULL;
+    const char *datastoreName = NULL;
+
+    if (sscanf(absolutePath, "/vmfs/volumes/%a[^/]/%a[^\n]",
+               &preliminaryDatastoreName, &directoryAndFileName) != 2) {
+        ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
+                  "Absolute path '%s' doesn't have expected format "
+                  "'/vmfs/volumes/<datastore>/<path>'", absolutePath);
+        goto failure;
+    }
+
+    if (ctx != NULL) {
+        if (esxVI_LookupDatastoreByName(conn, ctx, preliminaryDatastoreName,
+                                        NULL, &datastore,
+                                        esxVI_Occurence_RequiredItem) < 0) {
+            goto failure;
+        }
+
+        for (dynamicProperty = datastore->propSet; dynamicProperty != NULL;
+             dynamicProperty = dynamicProperty->_next) {
+            if (STREQ(dynamicProperty->name, "info.name")) {
+                if (esxVI_AnyType_ExpectType(conn, dynamicProperty->val,
+                                             esxVI_Type_String) < 0) {
+                    goto failure;
+                }
+
+                datastoreName = dynamicProperty->val->string;
+                break;
+            } else if (STREQ(dynamicProperty->name, "info.url")) {
+                /* Ignore it */
+            } else {
+                VIR_WARN("Unexpected '%s' property", dynamicProperty->name);
+            }
+        }
+
+        if (datastoreName == NULL) {
+            ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
+                      "Could not retrieve datastore name for absolute path '%s'",
+                      absolutePath);
+            goto failure;
+        }
+    } else {
+        datastoreName = preliminaryDatastoreName;
+    }
+
+    if (virAsprintf(&datastoreRelatedPath, "[%s] %s", datastoreName,
+                    directoryAndFileName) < 0) {
+        virReportOOMError(conn);
+        goto failure;
+    }
+
+    /* FIXME: Check if referenced path/file really exists */
+
+  cleanup:
+    VIR_FREE(preliminaryDatastoreName);
+    VIR_FREE(directoryAndFileName);
+    esxVI_ObjectContent_Free(&datastore);
+
+    return datastoreRelatedPath;
+
+  failure:
+    VIR_FREE(datastoreRelatedPath);
+
+    goto cleanup;
+}
+
+
+
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  * VMX -> Domain XML
  */
 
+char *
+esxVMX_ParseFileName(virConnectPtr conn, esxVI_Context *ctx,
+                     const char *fileName, const char *datastoreName,
+                     const char *directoryName)
+{
+    char *src = NULL;
+
+    if (STRPREFIX(fileName, "/vmfs/volumes/")) {
+        /* Found absolute path referencing a file inside a datastore */
+        return esxVMX_AbsolutePathToDatastoreRelatedPath(conn, ctx, fileName);
+    } else if (STRPREFIX(fileName, "/")) {
+        /* Found absolute path referencing a file outside a datastore */
+        src = strdup(fileName);
+
+        if (src == NULL) {
+            virReportOOMError(conn);
+            return NULL;
+        }
+
+        /* FIXME: Check if referenced path/file really exists */
+
+        return src;
+    } else if (strchr(fileName, '/') != NULL) {
+        /* Found relative path, this is not supported */
+        ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
+                  "Found relative path '%s' in VMX file, this is not "
+                  "supported", fileName);
+        return NULL;
+    } else {
+        /* Found single file name referencing a file inside a datastore */
+        if (virAsprintf(&src, "[%s] %s/%s", datastoreName, directoryName,
+                        fileName) < 0) {
+            virReportOOMError(conn);
+            return NULL;
+        }
+
+        /* FIXME: Check if referenced path/file really exists */
+
+        return src;
+    }
+}
+
+
+
 virDomainDefPtr
-esxVMX_ParseConfig(virConnectPtr conn, const char *vmx,
+esxVMX_ParseConfig(virConnectPtr conn, esxVI_Context *ctx, const char *vmx,
+                   const char *datastoreName, const char *directoryName,
                    esxVI_APIVersion apiVersion)
 {
     virConfPtr conf = NULL;
@@ -872,9 +994,9 @@ esxVMX_ParseConfig(virConnectPtr conn, const char *vmx,
                 continue;
             }
 
-            if (esxVMX_ParseDisk(conn, conf, VIR_DOMAIN_DISK_DEVICE_DISK,
+            if (esxVMX_ParseDisk(conn, ctx, conf, VIR_DOMAIN_DISK_DEVICE_DISK,
                                  VIR_DOMAIN_DISK_BUS_SCSI, controller, id,
-                                 scsi_virtualDev,
+                                 scsi_virtualDev, datastoreName, directoryName,
                                  &def->disks[def->ndisks]) < 0) {
                 goto failure;
             }
@@ -884,9 +1006,9 @@ esxVMX_ParseConfig(virConnectPtr conn, const char *vmx,
                 continue;
             }
 
-            if (esxVMX_ParseDisk(conn, conf, VIR_DOMAIN_DISK_DEVICE_CDROM,
+            if (esxVMX_ParseDisk(conn, ctx, conf, VIR_DOMAIN_DISK_DEVICE_CDROM,
                                  VIR_DOMAIN_DISK_BUS_SCSI, controller, id,
-                                 scsi_virtualDev,
+                                 scsi_virtualDev, datastoreName, directoryName,
                                  &def->disks[def->ndisks]) < 0) {
                 goto failure;
             }
@@ -900,9 +1022,10 @@ esxVMX_ParseConfig(virConnectPtr conn, const char *vmx,
     /* def:disks (ide) */
     for (controller = 0; controller < 2; ++controller) {
         for (id = 0; id < 2; ++id) {
-            if (esxVMX_ParseDisk(conn, conf, VIR_DOMAIN_DISK_DEVICE_DISK,
+            if (esxVMX_ParseDisk(conn, ctx, conf, VIR_DOMAIN_DISK_DEVICE_DISK,
                                  VIR_DOMAIN_DISK_BUS_IDE, controller, id,
-                                 NULL, &def->disks[def->ndisks]) < 0) {
+                                 NULL, datastoreName, directoryName,
+                                 &def->disks[def->ndisks]) < 0) {
                 goto failure;
             }
 
@@ -911,9 +1034,10 @@ esxVMX_ParseConfig(virConnectPtr conn, const char *vmx,
                 continue;
             }
 
-            if (esxVMX_ParseDisk(conn, conf, VIR_DOMAIN_DISK_DEVICE_CDROM,
+            if (esxVMX_ParseDisk(conn, ctx, conf, VIR_DOMAIN_DISK_DEVICE_CDROM,
                                  VIR_DOMAIN_DISK_BUS_IDE, controller, id,
-                                 NULL, &def->disks[def->ndisks]) < 0) {
+                                 NULL, datastoreName, directoryName,
+                                 &def->disks[def->ndisks]) < 0) {
                 goto failure;
             }
 
@@ -925,8 +1049,9 @@ esxVMX_ParseConfig(virConnectPtr conn, const char *vmx,
 
     /* def:disks (floppy) */
     for (controller = 0; controller < 2; ++controller) {
-        if (esxVMX_ParseDisk(conn, conf, VIR_DOMAIN_DISK_DEVICE_FLOPPY,
+        if (esxVMX_ParseDisk(conn, ctx, conf, VIR_DOMAIN_DISK_DEVICE_FLOPPY,
                              VIR_DOMAIN_DISK_BUS_FDC, controller, -1, NULL,
+                             datastoreName, directoryName,
                              &def->disks[def->ndisks]) < 0) {
             goto failure;
         }
@@ -976,7 +1101,8 @@ esxVMX_ParseConfig(virConnectPtr conn, const char *vmx,
     def->nserials = 0;
 
     for (port = 0; port < 4; ++port) {
-        if (esxVMX_ParseSerial(conn, conf, port,
+        if (esxVMX_ParseSerial(conn, ctx, conf, port,
+                               datastoreName, directoryName,
                                &def->serials[def->nserials]) < 0) {
             goto failure;
         }
@@ -995,7 +1121,8 @@ esxVMX_ParseConfig(virConnectPtr conn, const char *vmx,
     def->nparallels = 0;
 
     for (port = 0; port < 3; ++port) {
-        if (esxVMX_ParseParallel(conn, conf, port,
+        if (esxVMX_ParseParallel(conn, ctx, conf, port,
+                                 datastoreName, directoryName,
                                  &def->parallels[def->nparallels]) < 0) {
             goto failure;
         }
@@ -1118,9 +1245,10 @@ struct _virDomainDiskDef {
 };*/
 
 int
-esxVMX_ParseDisk(virConnectPtr conn, virConfPtr conf, int device, int bus,
-                 int controller, int id, const char *virtualDev,
-                 virDomainDiskDefPtr *def)
+esxVMX_ParseDisk(virConnectPtr conn, esxVI_Context *ctx, virConfPtr conf,
+                 int device, int bus, int controller, int id,
+                 const char *virtualDev, const char *datastoreName,
+                 const char *directoryName, virDomainDiskDefPtr *def)
 {
     /*
      *     device = {VIR_DOMAIN_DISK_DEVICE_DISK, VIR_DOMAIN_DISK_DEVICE_CDROM}
@@ -1345,7 +1473,6 @@ esxVMX_ParseDisk(virConnectPtr conn, virConfPtr conf, int device, int bus,
     }
 
     /* Setup virDomainDiskDef */
-    /* FIXME: Need the datastore name for fileName */
     if (device == VIR_DOMAIN_DISK_DEVICE_DISK) {
         if (esxUtil_EqualSuffix(fileName, ".vmdk")) {
             if (deviceType != NULL) {
@@ -1375,11 +1502,14 @@ esxVMX_ParseDisk(virConnectPtr conn, virConfPtr conf, int device, int bus,
             }
 
             (*def)->type = VIR_DOMAIN_DISK_TYPE_FILE;
-            (*def)->src = fileName;
+            (*def)->src = esxVMX_ParseFileName(conn, ctx, fileName,
+                                               datastoreName, directoryName);
             (*def)->cachemode = writeThrough ? VIR_DOMAIN_DISK_CACHE_WRITETHRU
                                              : VIR_DOMAIN_DISK_CACHE_DEFAULT;
 
-            fileName = NULL;
+            if ((*def)->src == NULL) {
+                goto failure;
+            }
         } else if (esxUtil_EqualSuffix(fileName, ".iso") ||
                    STREQ(deviceType, "atapi-cdrom")) {
             /*
@@ -1407,9 +1537,12 @@ esxVMX_ParseDisk(virConnectPtr conn, virConfPtr conf, int device, int bus,
             }
 
             (*def)->type = VIR_DOMAIN_DISK_TYPE_FILE;
-            (*def)->src = fileName;
+            (*def)->src = esxVMX_ParseFileName(conn, ctx, fileName,
+                                               datastoreName, directoryName);
 
-            fileName = NULL;
+            if ((*def)->src == NULL) {
+                goto failure;
+            }
         } else if (esxUtil_EqualSuffix(fileName, ".vmdk")) {
             /*
              * This function was called in order to parse a CDROM device, but
@@ -1441,9 +1574,12 @@ esxVMX_ParseDisk(virConnectPtr conn, virConfPtr conf, int device, int bus,
             }
 
             (*def)->type = VIR_DOMAIN_DISK_TYPE_FILE;
-            (*def)->src = fileName;
+            (*def)->src = esxVMX_ParseFileName(conn, ctx, fileName,
+                                               datastoreName, directoryName);
 
-            fileName = NULL;
+            if ((*def)->src == NULL) {
+                goto failure;
+            }
         } else if (fileType != NULL && STREQ(fileType, "device")) {
             (*def)->type = VIR_DOMAIN_DISK_TYPE_BLOCK;
             (*def)->src = fileName;
@@ -1695,8 +1831,9 @@ esxVMX_ParseEthernet(virConnectPtr conn, virConfPtr conf, int controller,
 
 
 int
-esxVMX_ParseSerial(virConnectPtr conn, virConfPtr conf, int port,
-                   virDomainChrDefPtr *def)
+esxVMX_ParseSerial(virConnectPtr conn, esxVI_Context *ctx, virConfPtr conf,
+                   int port, const char *datastoreName,
+                   const char *directoryName, virDomainChrDefPtr *def)
 {
     int result = 0;
     char prefix[48] = "";
@@ -1773,9 +1910,13 @@ esxVMX_ParseSerial(virConnectPtr conn, virConfPtr conf, int port,
     } else if (STRCASEEQ(fileType, "file")) {
         (*def)->dstPort = port;
         (*def)->type = VIR_DOMAIN_CHR_TYPE_FILE;
-        (*def)->data.file.path = fileName;
+        (*def)->data.file.path = esxVMX_ParseFileName(conn, ctx, fileName,
+                                                      datastoreName,
+                                                      directoryName);
 
-        fileName = NULL;
+        if ((*def)->data.file.path == NULL) {
+            goto failure;
+        }
     } else if (STRCASEEQ(fileType, "pipe")) {
         /*
          * FIXME: Differences between client/server and VM/application pipes
@@ -1812,8 +1953,9 @@ esxVMX_ParseSerial(virConnectPtr conn, virConfPtr conf, int port,
 
 
 int
-esxVMX_ParseParallel(virConnectPtr conn, virConfPtr conf, int port,
-                     virDomainChrDefPtr *def)
+esxVMX_ParseParallel(virConnectPtr conn, esxVI_Context *ctx, virConfPtr conf,
+                     int port, const char *datastoreName,
+                     const char *directoryName, virDomainChrDefPtr *def)
 {
     int result = 0;
     char prefix[48] = "";
@@ -1890,9 +2032,13 @@ esxVMX_ParseParallel(virConnectPtr conn, virConfPtr conf, int port,
     } else if (STRCASEEQ(fileType, "file")) {
         (*def)->dstPort = port;
         (*def)->type = VIR_DOMAIN_CHR_TYPE_FILE;
-        (*def)->data.file.path = fileName;
+        (*def)->data.file.path = esxVMX_ParseFileName(conn, ctx, fileName,
+                                                      datastoreName,
+                                                      directoryName);
 
-        fileName = NULL;
+        if ((*def)->data.file.path == NULL) {
+            goto failure;
+        }
     } else {
         ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
                   "Expecting VMX entry '%s' to be 'device' or 'file' but "
@@ -1923,8 +2069,70 @@ esxVMX_ParseParallel(virConnectPtr conn, virConfPtr conf, int port,
  */
 
 char *
-esxVMX_FormatConfig(virConnectPtr conn, virDomainDefPtr def,
-                    esxVI_APIVersion apiVersion)
+esxVMX_FormatFileName(virConnectPtr conn, esxVI_Context *ctx ATTRIBUTE_UNUSED,
+                      const char *src)
+{
+    char *datastoreName = NULL;
+    char *directoryName = NULL;
+    char *fileName = NULL;
+    char *absolutePath = NULL;
+
+    if (STRPREFIX(src, "[")) {
+        /* Found potential datastore related path */
+        if (esxUtil_ParseDatastoreRelatedPath(conn, src, &datastoreName,
+                                              &directoryName, &fileName) < 0) {
+            goto failure;
+        }
+
+        if (directoryName == NULL) {
+            if (virAsprintf(&absolutePath, "/vmfs/volumes/%s/%s",
+                            datastoreName, fileName) < 0) {
+                virReportOOMError(conn);
+                goto failure;
+            }
+        } else {
+            if (virAsprintf(&absolutePath, "/vmfs/volumes/%s/%s/%s",
+                            datastoreName, directoryName, fileName) < 0) {
+                virReportOOMError(conn);
+                goto failure;
+            }
+        }
+    } else if (STRPREFIX(src, "/")) {
+        /* Found absolute path */
+        absolutePath = strdup(src);
+
+        if (absolutePath == NULL) {
+            virReportOOMError(conn);
+            goto failure;
+        }
+    } else {
+        /* Found relative path, this is not supported */
+        ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
+                  "Found relative path '%s' in domain XML, this is not "
+                  "supported", src);
+        goto failure;
+    }
+
+    /* FIXME: Check if referenced path/file really exists */
+
+  cleanup:
+    VIR_FREE(datastoreName);
+    VIR_FREE(directoryName);
+    VIR_FREE(fileName);
+
+    return absolutePath;
+
+  failure:
+    VIR_FREE(absolutePath);
+
+    goto cleanup;
+}
+
+
+
+char *
+esxVMX_FormatConfig(virConnectPtr conn, esxVI_Context *ctx,
+                    virDomainDefPtr def, esxVI_APIVersion apiVersion)
 {
     int i;
     int sched_cpu_affinity_length;
@@ -2086,21 +2294,21 @@ esxVMX_FormatConfig(virConnectPtr conn, virDomainDefPtr def,
     for (i = 0; i < def->ndisks; ++i) {
         switch (def->disks[i]->device) {
           case VIR_DOMAIN_DISK_DEVICE_DISK:
-            if (esxVMX_FormatHardDisk(conn, def->disks[i], &buffer) < 0) {
+            if (esxVMX_FormatHardDisk(conn, ctx, def->disks[i], &buffer) < 0) {
                 goto failure;
             }
 
             break;
 
           case VIR_DOMAIN_DISK_DEVICE_CDROM:
-            if (esxVMX_FormatCDROM(conn, def->disks[i], &buffer) < 0) {
+            if (esxVMX_FormatCDROM(conn, ctx, def->disks[i], &buffer) < 0) {
                 goto failure;
             }
 
             break;
 
           case VIR_DOMAIN_DISK_DEVICE_FLOPPY:
-            if (esxVMX_FormatFloppy(conn, def->disks[i], &buffer) < 0) {
+            if (esxVMX_FormatFloppy(conn, ctx, def->disks[i], &buffer) < 0) {
                 goto failure;
             }
 
@@ -2135,14 +2343,14 @@ esxVMX_FormatConfig(virConnectPtr conn, virDomainDefPtr def,
 
     /* def:serials */
     for (i = 0; i < def->nserials; ++i) {
-        if (esxVMX_FormatSerial(conn, def->serials[i], &buffer) < 0) {
+        if (esxVMX_FormatSerial(conn, ctx, def->serials[i], &buffer) < 0) {
             goto failure;
         }
     }
 
     /* def:parallels */
     for (i = 0; i < def->nparallels; ++i) {
-        if (esxVMX_FormatParallel(conn, def->parallels[i], &buffer) < 0) {
+        if (esxVMX_FormatParallel(conn, ctx, def->parallels[i], &buffer) < 0) {
             goto failure;
         }
     }
@@ -2170,13 +2378,14 @@ esxVMX_FormatConfig(virConnectPtr conn, virDomainDefPtr def,
 
 
 int
-esxVMX_FormatHardDisk(virConnectPtr conn, virDomainDiskDefPtr def,
-                      virBufferPtr buffer)
+esxVMX_FormatHardDisk(virConnectPtr conn, esxVI_Context *ctx,
+                      virDomainDiskDefPtr def, virBufferPtr buffer)
 {
     int controller, id;
     const char *busName = NULL;
     const char *entryPrefix = NULL;
     const char *deviceTypePrefix = NULL;
+    char *fileName = NULL;
 
     if (def->device != VIR_DOMAIN_DISK_DEVICE_DISK) {
         ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR, "Invalid argument");
@@ -2229,8 +2438,16 @@ esxVMX_FormatHardDisk(virConnectPtr conn, virDomainDiskDefPtr def,
             return -1;
         }
 
+        fileName = esxVMX_FormatFileName(conn, ctx, def->src);
+
+        if (fileName == NULL) {
+            return -1;
+        }
+
         virBufferVSprintf(buffer, "%s%d:%d.fileName = \"%s\"\n",
-                          entryPrefix, controller, id, def->src);
+                          entryPrefix, controller, id, fileName);
+
+        VIR_FREE(fileName);
     }
 
     if (def->bus == VIR_DOMAIN_DISK_BUS_SCSI) {
@@ -2242,7 +2459,7 @@ esxVMX_FormatHardDisk(virConnectPtr conn, virDomainDiskDefPtr def,
                       "%s harddisk '%s' has unsupported cache mode '%s'",
                       busName, def->dst,
                       virDomainDiskCacheTypeToString(def->cachemode));
-           return -1;
+            return -1;
         }
     }
 
@@ -2252,12 +2469,13 @@ esxVMX_FormatHardDisk(virConnectPtr conn, virDomainDiskDefPtr def,
 
 
 int
-esxVMX_FormatCDROM(virConnectPtr conn, virDomainDiskDefPtr def,
-                   virBufferPtr buffer)
+esxVMX_FormatCDROM(virConnectPtr conn, esxVI_Context *ctx,
+                   virDomainDiskDefPtr def, virBufferPtr buffer)
 {
     int controller, id;
     const char *busName = NULL;
     const char *entryPrefix = NULL;
+    char *fileName = NULL;
 
     if (def->device != VIR_DOMAIN_DISK_DEVICE_CDROM) {
         ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR, "Invalid argument");
@@ -2293,9 +2511,34 @@ esxVMX_FormatCDROM(virConnectPtr conn, virDomainDiskDefPtr def,
     if (def->type == VIR_DOMAIN_DISK_TYPE_FILE) {
         virBufferVSprintf(buffer, "%s%d:%d.deviceType = \"cdrom-image\"\n",
                           entryPrefix, controller, id);
+
+        if (def->src != NULL) {
+            if (! esxUtil_EqualSuffix(def->src, ".iso")) {
+                ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
+                          "Image file for %s cdrom '%s' has unsupported "
+                          "suffix, expecting '.iso'", busName, def->dst);
+                return -1;
+            }
+
+            fileName = esxVMX_FormatFileName(conn, ctx, def->src);
+
+            if (fileName == NULL) {
+                return -1;
+            }
+
+            virBufferVSprintf(buffer, "%s%d:%d.fileName = \"%s\"\n",
+                              entryPrefix, controller, id, fileName);
+
+            VIR_FREE(fileName);
+        }
     } else if (def->type == VIR_DOMAIN_DISK_TYPE_BLOCK) {
         virBufferVSprintf(buffer, "%s%d:%d.deviceType = \"atapi-cdrom\"\n",
                           entryPrefix, controller, id);
+
+        if (def->src != NULL) {
+            virBufferVSprintf(buffer, "%s%d:%d.fileName = \"%s\"\n",
+                              entryPrefix, controller, id, def->src);
+        }
     } else {
         ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
                   "%s cdrom '%s' has unsupported type '%s', expecting '%s' "
@@ -2306,29 +2549,17 @@ esxVMX_FormatCDROM(virConnectPtr conn, virDomainDiskDefPtr def,
         return -1;
     }
 
-    if (def->src != NULL) {
-        if (def->type == VIR_DOMAIN_DISK_TYPE_FILE &&
-            ! esxUtil_EqualSuffix(def->src, ".iso")) {
-            ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
-                      "Image file for %s cdrom '%s' has unsupported suffix, "
-                      "expecting '.iso'", busName, def->dst);
-            return -1;
-        }
-
-        virBufferVSprintf(buffer, "%s%d:%d.fileName = \"%s\"\n",
-                          entryPrefix, controller, id, def->src);
-    }
-
     return 0;
 }
 
 
 
 int
-esxVMX_FormatFloppy(virConnectPtr conn, virDomainDiskDefPtr def,
-                    virBufferPtr buffer)
+esxVMX_FormatFloppy(virConnectPtr conn, esxVI_Context *ctx,
+                    virDomainDiskDefPtr def, virBufferPtr buffer)
 {
     int controller;
+    char *fileName = NULL;
 
     if (def->device != VIR_DOMAIN_DISK_DEVICE_FLOPPY) {
         ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR, "Invalid argument");
@@ -2344,9 +2575,34 @@ esxVMX_FormatFloppy(virConnectPtr conn, virDomainDiskDefPtr def,
     if (def->type == VIR_DOMAIN_DISK_TYPE_FILE) {
         virBufferVSprintf(buffer, "floppy%d.fileType = \"file\"\n",
                           controller);
+
+        if (def->src != NULL) {
+            if (! esxUtil_EqualSuffix(def->src, ".flp")) {
+                ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
+                          "Image file for floppy '%s' has unsupported suffix, "
+                          "expecting '.flp'", def->dst);
+                return -1;
+            }
+
+            fileName = esxVMX_FormatFileName(conn, ctx, def->src);
+
+            if (fileName == NULL) {
+                return -1;
+            }
+
+            virBufferVSprintf(buffer, "floppy%d.fileName = \"%s\"\n",
+                              controller, fileName);
+
+            VIR_FREE(fileName);
+        }
     } else if (def->type == VIR_DOMAIN_DISK_TYPE_BLOCK) {
         virBufferVSprintf(buffer, "floppy%d.fileType = \"device\"\n",
                           controller);
+
+        if (def->src != NULL) {
+            virBufferVSprintf(buffer, "floppy%d.fileName = \"%s\"\n",
+                              controller, def->src);
+        }
     } else {
         ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
                   "Floppy '%s' has unsupported type '%s', expecting '%s' "
@@ -2357,19 +2613,6 @@ esxVMX_FormatFloppy(virConnectPtr conn, virDomainDiskDefPtr def,
         return -1;
     }
 
-    if (def->src != NULL) {
-        if (def->type == VIR_DOMAIN_DISK_TYPE_FILE &&
-            ! esxUtil_EqualSuffix(def->src, ".flp")) {
-            ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
-                      "Image file for floppy '%s' has unsupported suffix, "
-                      "expecting '.flp'", def->dst);
-            return -1;
-        }
-
-        virBufferVSprintf(buffer, "floppy%d.fileName = \"%s\"\n", controller,
-                          def->src);
-    }
-
     return 0;
 }
 
@@ -2433,17 +2676,12 @@ esxVMX_FormatEthernet(virConnectPtr conn, virDomainNetDefPtr def,
 
     virFormatMacAddr(def->mac, mac_string);
 
-    if (def->mac[0] == 0x00 && def->mac[1] == 0x0c && def->mac[2] == 0x29) {
+    if ((def->mac[0] == 0x00 && def->mac[1] == 0x0c && def->mac[2] == 0x29) ||
+        (def->mac[0] == 0x00 && def->mac[1] == 0x50 && def->mac[2] == 0x56)) {
         virBufferVSprintf(buffer, "ethernet%d.addressType = \"generated\"\n",
                           controller);
         virBufferVSprintf(buffer, "ethernet%d.generatedAddress = \"%s\"\n",
                           controller, mac_string);
-    } else if (def->mac[0] == 0x00 && def->mac[1] == 0x50 &&
-               def->mac[2] == 0x56) {
-        virBufferVSprintf(buffer, "ethernet%d.addressType = \"static\"\n",
-                          controller);
-        virBufferVSprintf(buffer, "ethernet%d.address = \"%s\"\n",
-                          controller, mac_string);
     } else {
         ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
                   "Unsupported MAC address prefix '%02X:%02X:%02X', expecting "
@@ -2458,9 +2696,11 @@ esxVMX_FormatEthernet(virConnectPtr conn, virDomainNetDefPtr def,
 
 
 int
-esxVMX_FormatSerial(virConnectPtr conn, virDomainChrDefPtr def,
-                    virBufferPtr buffer)
+esxVMX_FormatSerial(virConnectPtr conn, esxVI_Context *ctx,
+                    virDomainChrDefPtr def, virBufferPtr buffer)
 {
+    char *fileName = NULL;
+
     if (def->dstPort < 0 || def->dstPort > 3) {
         ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
                   "Serial port index %d out of [0..3] range", def->dstPort);
@@ -2476,16 +2716,29 @@ esxVMX_FormatSerial(virConnectPtr conn, virDomainChrDefPtr def,
 
     virBufferVSprintf(buffer, "serial%d.present = \"true\"\n", def->dstPort);
 
-    /* def:type -> vmx:fileType */
+    /* def:type -> vmx:fileType and def:data.file.path -> vmx:fileName */
     switch (def->type) {
       case VIR_DOMAIN_CHR_TYPE_DEV:
         virBufferVSprintf(buffer, "serial%d.fileType = \"device\"\n",
                           def->dstPort);
+        virBufferVSprintf(buffer, "serial%d.fileName = \"%s\"\n",
+                          def->dstPort, def->data.file.path);
         break;
 
       case VIR_DOMAIN_CHR_TYPE_FILE:
         virBufferVSprintf(buffer, "serial%d.fileType = \"file\"\n",
                           def->dstPort);
+
+        fileName = esxVMX_FormatFileName(conn, ctx, def->data.file.path);
+
+        if (fileName == NULL) {
+            return -1;
+        }
+
+        virBufferVSprintf(buffer, "serial%d.fileName = \"%s\"\n",
+                          def->dstPort, fileName);
+
+        VIR_FREE(fileName);
         break;
 
       case VIR_DOMAIN_CHR_TYPE_PIPE:
@@ -2497,6 +2750,8 @@ esxVMX_FormatSerial(virConnectPtr conn, virDomainChrDefPtr def,
         /* FIXME: Based on VI Client GUI default */
         virBufferVSprintf(buffer, "serial%d.tryNoRxLoss = \"false\"\n",
                           def->dstPort);
+        virBufferVSprintf(buffer, "serial%d.fileName = \"%s\"\n",
+                          def->dstPort, def->data.file.path);
         break;
 
       default:
@@ -2506,10 +2761,6 @@ esxVMX_FormatSerial(virConnectPtr conn, virDomainChrDefPtr def,
         return -1;
     }
 
-    /* def:data.file.path -> vmx:fileName */
-    virBufferVSprintf(buffer, "serial%d.fileName = \"%s\"\n",
-                      def->dstPort, def->data.file.path);
-
     /* vmx:yieldOnMsrRead */
     /* FIXME: Based on VI Client GUI default */
     virBufferVSprintf(buffer, "serial%d.yieldOnMsrRead = \"true\"\n",
@@ -2521,9 +2772,11 @@ esxVMX_FormatSerial(virConnectPtr conn, virDomainChrDefPtr def,
 
 
 int
-esxVMX_FormatParallel(virConnectPtr conn, virDomainChrDefPtr def,
-                      virBufferPtr buffer)
+esxVMX_FormatParallel(virConnectPtr conn, esxVI_Context *ctx,
+                      virDomainChrDefPtr def, virBufferPtr buffer)
 {
+    char *fileName = NULL;
+
     if (def->dstPort < 0 || def->dstPort > 2) {
         ESX_ERROR(conn, VIR_ERR_INTERNAL_ERROR,
                   "Parallel port index %d out of [0..2] range", def->dstPort);
@@ -2539,16 +2792,29 @@ esxVMX_FormatParallel(virConnectPtr conn, virDomainChrDefPtr def,
 
     virBufferVSprintf(buffer, "parallel%d.present = \"true\"\n", def->dstPort);
 
-    /* def:type -> vmx:fileType */
+    /* def:type -> vmx:fileType and def:data.file.path -> vmx:fileName */
     switch (def->type) {
       case VIR_DOMAIN_CHR_TYPE_DEV:
         virBufferVSprintf(buffer, "parallel%d.fileType = \"device\"\n",
                           def->dstPort);
+        virBufferVSprintf(buffer, "parallel%d.fileName = \"%s\"\n",
+                          def->dstPort, def->data.file.path);
         break;
 
       case VIR_DOMAIN_CHR_TYPE_FILE:
         virBufferVSprintf(buffer, "parallel%d.fileType = \"file\"\n",
                           def->dstPort);
+
+        fileName = esxVMX_FormatFileName(conn, ctx, def->data.file.path);
+
+        if (fileName == NULL) {
+            return -1;
+        }
+
+        virBufferVSprintf(buffer, "parallel%d.fileName = \"%s\"\n",
+                          def->dstPort, fileName);
+
+        VIR_FREE(fileName);
         break;
 
       default:
@@ -2558,9 +2824,5 @@ esxVMX_FormatParallel(virConnectPtr conn, virDomainChrDefPtr def,
         return -1;
     }
 
-    /* def:data.file.path -> vmx:fileName */
-    virBufferVSprintf(buffer, "parallel%d.fileName = \"%s\"\n",
-                      def->dstPort, def->data.file.path);
-
     return 0;
 }
index 1d77232d228730c77fdb773bdd70b6a6f1cdc299..4e11ae6444c49acc2a07c7ac26cce5b19866e23c 100644 (file)
@@ -34,9 +34,11 @@ esxVMX_IndexToDiskName(virConnectPtr conn, int idx, const char *prefix);
 int
 esxVMX_SCSIDiskNameToControllerAndID(virConnectPtr conn, const char *name,
                                      int *controller, int *id);
+
 int
 esxVMX_IDEDiskNameToControllerAndID(virConnectPtr conn, const char *name,
-                                     int *controller, int *id);
+                                    int *controller, int *id);
+
 int
 esxVMX_FloppyDiskNameToController(virConnectPtr conn, const char *name,
                                   int *controller);
@@ -45,14 +47,24 @@ int
 esxVMX_GatherSCSIControllers(virConnectPtr conn, virDomainDefPtr conf,
                              char *virtualDev[4], int present[4]);
 
+char *
+esxVMX_AbsolutePathToDatastoreRelatedPath(virConnectPtr conn,
+                                          esxVI_Context *ctx,
+                                          const char *absolutePath);
 
 
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  * VMX -> Domain XML
  */
 
+char *
+esxVMX_ParseFileName(virConnectPtr conn, esxVI_Context *ctx,
+                     const char *fileName, const char *datastoreName,
+                     const char *directoryName);
+
 virDomainDefPtr
-esxVMX_ParseConfig(virConnectPtr conn, const char *vmx,
+esxVMX_ParseConfig(virConnectPtr conn, esxVI_Context *ctx, const char *vmx,
+                   const char *datastoreName, const char *directoryName,
                    esxVI_APIVersion apiVersion);
 
 int
@@ -60,20 +72,23 @@ esxVMX_ParseSCSIController(virConnectPtr conn, virConfPtr conf,
                            int controller, int *present, char **virtualDev);
 
 int
-esxVMX_ParseDisk(virConnectPtr conn, virConfPtr conf, int device, int bus,
-                 int controller, int id, const char *virtualDev,
-                 virDomainDiskDefPtr *def);
+esxVMX_ParseDisk(virConnectPtr conn, esxVI_Context *ctx, virConfPtr conf,
+                 int device, int bus, int controller, int id,
+                 const char *virtualDev, const char *datastoreName,
+                 const char *directoryName, virDomainDiskDefPtr *def);
 int
 esxVMX_ParseEthernet(virConnectPtr conn, virConfPtr conf, int controller,
                      virDomainNetDefPtr *def);
 
 int
-esxVMX_ParseSerial(virConnectPtr conn, virConfPtr conf, int port,
-                   virDomainChrDefPtr *def);
+esxVMX_ParseSerial(virConnectPtr conn, esxVI_Context *ctx, virConfPtr conf,
+                   int port, const char *datastoreName,
+                   const char *directoryName, virDomainChrDefPtr *def);
 
 int
-esxVMX_ParseParallel(virConnectPtr conn, virConfPtr conf, int port,
-                     virDomainChrDefPtr *def);
+esxVMX_ParseParallel(virConnectPtr conn, esxVI_Context *ctx, virConfPtr conf,
+                     int port, const char *datastoreName,
+                     const char *directoryName, virDomainChrDefPtr *def);
 
 
 
@@ -82,31 +97,34 @@ esxVMX_ParseParallel(virConnectPtr conn, virConfPtr conf, int port,
  */
 
 char *
-esxVMX_FormatConfig(virConnectPtr conn, virDomainDefPtr def,
-                    esxVI_APIVersion apiVersion);
+esxVMX_FormatFileName(virConnectPtr conn, esxVI_Context *ctx, const char *src);
+
+char *
+esxVMX_FormatConfig(virConnectPtr conn, esxVI_Context *ctx,
+                    virDomainDefPtr def, esxVI_APIVersion apiVersion);
 
 int
-esxVMX_FormatHardDisk(virConnectPtr conn, virDomainDiskDefPtr def,
-                      virBufferPtr buffer);
+esxVMX_FormatHardDisk(virConnectPtr conn, esxVI_Context *ctx,
+                      virDomainDiskDefPtr def, virBufferPtr buffer);
 
 int
-esxVMX_FormatCDROM(virConnectPtr conn, virDomainDiskDefPtr def,
-                   virBufferPtr buffer);
+esxVMX_FormatCDROM(virConnectPtr conn, esxVI_Context *ctx,
+                   virDomainDiskDefPtr def, virBufferPtr buffer);
 
 int
-esxVMX_FormatFloppy(virConnectPtr conn, virDomainDiskDefPtr def,
-                    virBufferPtr buffer);
+esxVMX_FormatFloppy(virConnectPtr conn, esxVI_Context *ctx,
+                    virDomainDiskDefPtr def, virBufferPtr buffer);
 
 int
 esxVMX_FormatEthernet(virConnectPtr conn, virDomainNetDefPtr def,
                       int controller, virBufferPtr buffer);
 
 int
-esxVMX_FormatSerial(virConnectPtr conn, virDomainChrDefPtr def,
-                    virBufferPtr buffer);
+esxVMX_FormatSerial(virConnectPtr conn, esxVI_Context *ctx,
+                    virDomainChrDefPtr def, virBufferPtr buffer);
 
 int
-esxVMX_FormatParallel(virConnectPtr conn, virDomainChrDefPtr def,
-                      virBufferPtr buffer);
+esxVMX_FormatParallel(virConnectPtr conn, esxVI_Context *ctx,
+                      virDomainChrDefPtr def, virBufferPtr buffer);
 
 #endif /* __ESX_VMX_H__ */
index 7eca1befb0d77a483187001e576ea007b0c914f6..5633ee24e2014d55e07f491e0aeb34c0fe3d3e5b 100644 (file)
@@ -9,15 +9,21 @@
 #include "internal.h"
 #include "memory.h"
 #include "testutils.h"
+#include "esx/esx_util.h"
 #include "esx/esx_vmx.h"
 
 static char *progname;
 
-struct testInfo {
-    const char *input;
-    const char *output;
-    esxVI_APIVersion version;
-};
+
+
+static void
+testQuietError(void *userData ATTRIBUTE_UNUSED,
+               virErrorPtr error ATTRIBUTE_UNUSED)
+{
+    /* nothing */
+}
+
+
 
 static const char* names[] = {
     "sda",  "sdb",  "sdc",  "sdd",  "sde",  "sdf",  "sdg",  "sdh",  "sdi",  "sdj",  "sdk",  "sdl",  "sdm",  "sdn",  "sdo",  "sdp",  "sdq",  "sdr",  "sds",  "sdt",  "sdu",  "sdv",  "sdw",  "sdx",  "sdy",  "sdz",
@@ -62,6 +68,80 @@ testIndexToDiskName(const void *data ATTRIBUTE_UNUSED)
     return 0;
 }
 
+
+
+struct testPath {
+    const char *datastoreRelatedPath;
+    int result;
+    const char *datastoreName;
+    const char *directoryName;
+    const char *fileName;
+};
+
+static struct testPath paths[] = {
+    { "[datastore] directory/file", 0, "datastore", "directory", "file" },
+    { "[datastore] file", 0, "datastore", NULL, "file" },
+    { "[] directory/file", -1, NULL, NULL, NULL },
+    { "[datastore] directory/", -1, NULL, NULL, NULL },
+    { "directory/file", -1, NULL, NULL, NULL },
+};
+
+static int
+testParseDatastoreRelatedPath(const void *data ATTRIBUTE_UNUSED)
+{
+    int i, result = 0;
+    char *datastoreName = NULL;
+    char *directoryName = NULL;
+    char *fileName = NULL;
+
+    for (i = 0; i < ARRAY_CARDINALITY(paths); ++i) {
+        VIR_FREE(datastoreName);
+        VIR_FREE(directoryName);
+        VIR_FREE(fileName);
+
+        if (esxUtil_ParseDatastoreRelatedPath(NULL,
+                                              paths[i].datastoreRelatedPath,
+                                              &datastoreName, &directoryName,
+                                              &fileName) != paths[i].result) {
+            goto failure;
+        }
+
+        if (paths[i].result < 0) {
+            continue;
+        }
+
+        if (STRNEQ(paths[i].datastoreName, datastoreName)) {
+            virtTestDifference(stderr, paths[i].datastoreName, datastoreName);
+            goto failure;
+        }
+
+        if (paths[i].directoryName != NULL &&
+            STRNEQ(paths[i].directoryName, directoryName)) {
+            virtTestDifference(stderr, paths[i].directoryName, directoryName);
+            goto failure;
+        }
+
+        if (STRNEQ(paths[i].fileName, fileName)) {
+            virtTestDifference(stderr, paths[i].fileName, fileName);
+            goto failure;
+        }
+    }
+
+  cleanup:
+    VIR_FREE(datastoreName);
+    VIR_FREE(directoryName);
+    VIR_FREE(fileName);
+
+    return result;
+
+  failure:
+    result = -1;
+
+    goto cleanup;
+}
+
+
+
 static int
 mymain(int argc, char **argv)
 {
@@ -79,10 +159,18 @@ mymain(int argc, char **argv)
         return EXIT_FAILURE;
     }
 
-    if (virtTestRun("VMware IndexToDiskName", 1, testIndexToDiskName,
-                    NULL) < 0) {
-        result = -1;
-    }
+    virSetErrorFunc(NULL, testQuietError);
+
+    #define DO_TEST(_name)                                                    \
+        do {                                                                  \
+            if (virtTestRun("VMware "#_name, 1, test##_name,                  \
+                            NULL) < 0) {                                      \
+                result = -1;                                                  \
+            }                                                                 \
+        } while (0)
+
+    DO_TEST(IndexToDiskName);
+    DO_TEST(ParseDatastoreRelatedPath);
 
     return result == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
 }
index 37451481d8eb03d23258638457007810b84b1b9f..c88d90e77ef3693788c6c2295d44a2bb4fa975ea 100644 (file)
@@ -12,7 +12,7 @@
   <on_crash>destroy</on_crash>
   <devices>
     <disk type='file' device='cdrom'>
-      <source file='cdrom.iso'/>
+      <source file='[datastore] directory/cdrom.iso'/>
       <target dev='hda' bus='ide'/>
     </disk>
   </devices>
index 2d37bdec45dcdcaadac5a81b8ab6839ca645bd64..ebd57180edd05f55aa0d0632d1e096b968edc49c 100644 (file)
@@ -12,7 +12,7 @@
   <on_crash>destroy</on_crash>
   <devices>
     <disk type='file' device='cdrom'>
-      <source file='cdrom.iso'/>
+      <source file='[datastore] directory/cdrom.iso'/>
       <target dev='sda' bus='scsi'/>
     </disk>
   </devices>
index 8a004747b7f7b480b41670044274d80792f76364..7cda8b5d99e4bba0297ee807c0ed9c07761570f9 100644 (file)
@@ -14,7 +14,7 @@
   <devices>
     <disk type='file' device='disk'>
       <driver name='lsilogic'/>
-      <source file='Fedora11.vmdk'/>
+      <source file='[datastore] directory/Fedora11.vmdk'/>
       <target dev='sda' bus='scsi'/>
     </disk>
     <interface type='bridge'>
index 62e8bb4ab4c4af5080b60a762ca5e0f515f91dcb..95fb40b42d91dc9767509aa2b17ac3ad9ccb1bd1 100644 (file)
   <devices>
     <disk type='file' device='disk'>
       <driver name='lsilogic' cache='writethrough'/>
-      <source file='Debian1.vmdk'/>
+      <source file='[datastore] directory/Debian1.vmdk'/>
       <target dev='sda' bus='scsi'/>
     </disk>
     <disk type='file' device='cdrom'>
       <driver name='buslogic'/>
-      <source file='Debian1-cdrom.iso'/>
+      <source file='[datastore] directory/Debian1-cdrom.iso'/>
       <target dev='sdp' bus='scsi'/>
     </disk>
     <disk type='file' device='cdrom'>
@@ -31,7 +31,7 @@
       <target dev='hdb' bus='ide'/>
     </disk>
     <disk type='file' device='disk'>
-      <source file='Debian1-IDE.vmdk'/>
+      <source file='[datastore] directory/Debian1-IDE.vmdk'/>
       <target dev='hdd' bus='ide'/>
     </disk>
     <disk type='block' device='floppy'>
index 3f85cb429b979abfdfb7ce49a094620716fa053e..ea30c434ba03b4844d8df108655219dda7b5b0cc 100644 (file)
   <devices>
     <disk type='file' device='disk'>
       <driver name='lsilogic'/>
-      <source file='Debian2.vmdk'/>
+      <source file='[datastore] directory/Debian2.vmdk'/>
       <target dev='sda' bus='scsi'/>
     </disk>
     <disk type='file' device='cdrom'>
-      <source file='/vmfs/volumes/498076b2-02796c1a-ef5b-000ae484a6a3/Isos/debian-testing-amd64-netinst.iso'/>
+      <source file='[498076b2-02796c1a-ef5b-000ae484a6a3] Isos/debian-testing-amd64-netinst.iso'/>
       <target dev='hda' bus='ide'/>
     </disk>
     <disk type='file' device='floppy'>
-      <source file='/vmfs/volumes/498076b2-02796c1a-ef5b-000ae484a6a3/Debian2/dummy.flp'/>
+      <source file='[498076b2-02796c1a-ef5b-000ae484a6a3] Debian2/dummy.flp'/>
       <target dev='fdb' bus='fdc'/>
     </disk>
     <interface type='bridge'>
index f539dced9831b995bb4e68556497d2d1bc044032..3a4c6ae71b069f09470692794825012eb43972c6 100644 (file)
@@ -14,7 +14,7 @@
   <devices>
     <disk type='file' device='disk'>
       <driver name='lsilogic'/>
-      <source file='virtMonServ1.vmdk'/>
+      <source file='[datastore] directory/virtMonServ1.vmdk'/>
       <target dev='sda' bus='scsi'/>
     </disk>
     <interface type='bridge'>
       <source bridge='VM Switch 2'/>
     </interface>
     <serial type='file'>
-      <source path='/vmfs/volumes/498076b2-02796c1a-ef5b-000ae484a6a3/virtMonServ1/serial1.file'/>
+      <source path='[498076b2-02796c1a-ef5b-000ae484a6a3] virtMonServ1/serial1.file'/>
       <target port='0'/>
     </serial>
     <parallel type='file'>
-      <source path='/vmfs/volumes/498076b2-02796c1a-ef5b-000ae484a6a3/virtMonServ1/parallel1.file'/>
+      <source path='[498076b2-02796c1a-ef5b-000ae484a6a3] virtMonServ1/parallel1.file'/>
       <target port='0'/>
     </parallel>
     <console type='file'>
-      <source path='/vmfs/volumes/498076b2-02796c1a-ef5b-000ae484a6a3/virtMonServ1/serial1.file'/>
+      <source path='[498076b2-02796c1a-ef5b-000ae484a6a3] virtMonServ1/serial1.file'/>
       <target port='0'/>
     </console>
   </devices>
index 03c782411c74be03623ac15be09939a2c8a617db..5c2e7e3f9bba0cb0da95c44b0cb4ba3e1554ab66 100644 (file)
@@ -12,7 +12,7 @@
   <on_crash>destroy</on_crash>
   <devices>
     <disk type='file' device='floppy'>
-      <source file='floppy.flp'/>
+      <source file='[datastore] directory/floppy.flp'/>
       <target dev='fda' bus='fdc'/>
     </disk>
   </devices>
index c1c2e05c7aa32ab319a533dae060f1aa7c57ba60..89a70a4bfbb1f0468e82ddece388ab1a93b93aaf 100644 (file)
@@ -13,7 +13,7 @@
   <on_crash>destroy</on_crash>
   <devices>
     <disk type='file' device='disk'>
-      <source file='Debian-System1-0-cl2.vmdk'/>
+      <source file='[datastore] directory/Debian-System1-0-cl2.vmdk'/>
       <target dev='hda' bus='ide'/>
     </disk>
     <interface type='bridge'>
index d71dc16e5c5684a8275a33d270c395b1784d886e..5f23d6045098089a3c46c5b94bbf75ccb4cb1409 100644 (file)
@@ -13,7 +13,7 @@
   <on_crash>destroy</on_crash>
   <devices>
     <disk type='file' device='disk'>
-      <source file='Debian-System1-0-cl3.vmdk'/>
+      <source file='[datastore] directory/Debian-System1-0-cl3.vmdk'/>
       <target dev='hda' bus='ide'/>
     </disk>
     <interface type='bridge'>
index 370dd57fc1e14f4b99e0a8f69601b3ee3e46f463..6f54b277fddfb95d9c850d33b5ffe7d76d89c094 100644 (file)
@@ -13,7 +13,7 @@
   <on_crash>destroy</on_crash>
   <devices>
     <disk type='file' device='disk'>
-      <source file='Debian-System1-0-cl1.vmdk'/>
+      <source file='[datastore] directory/Debian-System1-0-cl1.vmdk'/>
       <target dev='hda' bus='ide'/>
     </disk>
     <interface type='bridge'>
index 3b01392058ed0514e677ae8e1e384bda5c6a6926..5b8d64ed0d5e998ac091c046f8b142368130584b 100644 (file)
@@ -13,7 +13,7 @@
   <on_crash>destroy</on_crash>
   <devices>
     <disk type='file' device='disk'>
-      <source file='Debian-System1-0-cl2.vmdk'/>
+      <source file='[datastore] directory/Debian-System1-0-cl2.vmdk'/>
       <target dev='hda' bus='ide'/>
     </disk>
     <interface type='bridge'>
index c507ea21e2695b038bee30801416f9378bf108c7..59041bda67013b10fb68affde64713e8c529d6e3 100644 (file)
@@ -12,7 +12,7 @@
   <on_crash>destroy</on_crash>
   <devices>
     <disk type='file' device='disk'>
-      <source file='harddisk.vmdk'/>
+      <source file='[datastore] directory/harddisk.vmdk'/>
       <target dev='hda' bus='ide'/>
     </disk>
   </devices>
index 6b8b4fc1d13efd908f23612e305d1b86c4909975..2609f8c9056f55a25bdae459cbf540e9913adefb 100644 (file)
@@ -12,7 +12,7 @@
   <on_crash>destroy</on_crash>
   <devices>
     <disk type='file' device='disk'>
-      <source file='harddisk.vmdk'/>
+      <source file='[datastore] directory/harddisk.vmdk'/>
       <target dev='sda' bus='scsi'/>
     </disk>
   </devices>
index 77c8119ec3b066f7af118cb98e1c7bb5a3c1be61..340cf4e30a3c708144db58b51f0752cdd1acdd6b 100644 (file)
@@ -12,7 +12,7 @@
   <on_crash>destroy</on_crash>
   <devices>
     <parallel type='file'>
-      <source path='parallel0.file'/>
+      <source path='[datastore] directory/parallel0.file'/>
       <target port='0'/>
     </parallel>
   </devices>
index 2c12348b6ab2bd53268785c550e67439f427c745..2ffb8664ccecae06b2c06598ebb8c880d355d6b5 100644 (file)
@@ -13,7 +13,7 @@
   <devices>
     <disk type='file' device='disk'>
       <driver name='buslogic'/>
-      <source file='harddisk.vmdk'/>
+      <source file='[datastore] directory/harddisk.vmdk'/>
       <target dev='sda' bus='scsi'/>
     </disk>
   </devices>
index 3c3a8e08867d15dc0d2ae1e8ec537b44a7584bcb..f1c40830d320861863f2c483a3021a77fc5aee1c 100644 (file)
@@ -13,7 +13,7 @@
   <devices>
     <disk type='file' device='disk'>
       <driver name='buslogic' cache='writethrough'/>
-      <source file='harddisk.vmdk'/>
+      <source file='[datastore] directory/harddisk.vmdk'/>
       <target dev='sda' bus='scsi'/>
     </disk>
   </devices>
index 55b44c5b6e1a3101a3d40b7d9cd7701099a8244b..95816e02a623a59da3a42d02bc200040c61d657a 100644 (file)
   <on_crash>destroy</on_crash>
   <devices>
     <serial type='file'>
-      <source path='serial0.file'/>
+      <source path='[datastore] directory/serial0.file'/>
       <target port='0'/>
     </serial>
     <console type='file'>
-      <source path='serial0.file'/>
+      <source path='[datastore] directory/serial0.file'/>
       <target port='0'/>
     </console>
   </devices>
index 5c344d0d7363f799b4714cf7e53198bf938daf2a..150a58d17dccd0e642c6d19f8d2a3d0655862351 100644 (file)
@@ -35,7 +35,8 @@ testCompareFiles(const char *vmx, const char *xml, esxVI_APIVersion apiVersion)
         goto failure;
     }
 
-    def = esxVMX_ParseConfig(NULL, vmxData, apiVersion);
+    def = esxVMX_ParseConfig(NULL, NULL, vmxData, "datastore", "directory",
+                             apiVersion);
 
     if (def == NULL) {
         goto failure;
index efcff55ee93c6de8c0125e9422ec2d7ffd27578b..e7a781904adc9de7ab34a0052bd9a39e494f5726 100644 (file)
@@ -7,4 +7,4 @@ memsize = "4"
 numvcpus = "1"
 ide0:0.present = "true"
 ide0:0.deviceType = "cdrom-image"
-ide0:0.fileName = "cdrom.iso"
+ide0:0.fileName = "/vmfs/volumes/testing/isos/cdrom.iso"
index f54bced6df06280b3df3969991f980176b7a3046..a2404da1b22151a3cb4e0727bd36f0ad45d12110 100644 (file)
@@ -7,7 +7,7 @@
   </os>
   <devices>
     <disk type='file' device='cdrom'>
-      <source file='cdrom.iso'/>
+      <source file='[testing] isos/cdrom.iso'/>
       <target dev='hda' bus='ide'/>
     </disk>
   </devices>
index 29f2d41062a9f6c833ea9b74719fc9d5f5fd4d61..396fb673aa92a32805504d06a061fc50d223c97e 100644 (file)
@@ -8,4 +8,4 @@ numvcpus = "1"
 scsi0.present = "true"
 scsi0:0.present = "true"
 scsi0:0.deviceType = "cdrom-image"
-scsi0:0.fileName = "cdrom.iso"
+scsi0:0.fileName = "/vmfs/volumes/testing/isos/cdrom.iso"
index 0f21dcfab98938fd3380454cc71194d6b4e8edae..2f2850920001f1099310749a2ffed6f44c0bd09a 100644 (file)
@@ -7,7 +7,7 @@
   </os>
   <devices>
     <disk type='file' device='cdrom'>
-      <source file='cdrom.iso'/>
+      <source file='[testing] isos/cdrom.iso'/>
       <target dev='sda' bus='scsi'/>
     </disk>
   </devices>
index b9a18ef02d717e4c09788acde4d7d7138a8ebad7..ea14588c9894b6e4a14ea71b90a9765863a3f2bf 100644 (file)
@@ -9,9 +9,9 @@ scsi0.present = "true"
 scsi0.virtualDev = "lsilogic"
 scsi0:0.present = "true"
 scsi0:0.deviceType = "scsi-hardDisk"
-scsi0:0.fileName = "Fedora11.vmdk"
+scsi0:0.fileName = "/vmfs/volumes/498076b2-02796c1a-ef5b-000ae484a6a3/Fedora11/Fedora11.vmdk"
 ethernet0.present = "true"
 ethernet0.networkName = "VM Network"
 ethernet0.connectionType = "bridged"
-ethernet0.addressType = "static"
-ethernet0.address = "00:50:56:91:48:C7"
+ethernet0.addressType = "generated"
+ethernet0.generatedAddress = "00:50:56:91:48:C7"
index eb0e9ef9736b35b76f07779dd6080f9a4b7ca04a..3f4ff8830d9a9540bb5529355e46db556816b23d 100644 (file)
@@ -14,7 +14,7 @@
   <devices>
     <disk type='file' device='disk'>
       <driver name='lsilogic'/>
-      <source file='Fedora11.vmdk'/>
+      <source file='[498076b2-02796c1a-ef5b-000ae484a6a3] Fedora11/Fedora11.vmdk'/>
       <target dev='sda' bus='scsi'/>
     </disk>
     <interface type='bridge'>
index 43714c182f3c89ddf0dfe63286e6ee93a9b5bb6c..05e3d4675a80a125d854810a0a75d69e4739da57 100644 (file)
@@ -13,11 +13,11 @@ scsi1.present = "true"
 scsi1.virtualDev = "buslogic"
 scsi0:0.present = "true"
 scsi0:0.deviceType = "scsi-hardDisk"
-scsi0:0.fileName = "Debian1.vmdk"
+scsi0:0.fileName = "/vmfs/volumes/498076b2-02796c1a-ef5b-000ae484a6a3/virtDebian1/Debian1.vmdk"
 scsi0:0.writeThrough = "true"
 scsi1:0.present = "true"
 scsi1:0.deviceType = "cdrom-image"
-scsi1:0.fileName = "Debian1-cdrom.iso"
+scsi1:0.fileName = "/vmfs/volumes/498076b2-02796c1a-ef5b-000ae484a6a3/virtDebian1/Debian1-cdrom.iso"
 ide0:0.present = "true"
 ide0:0.deviceType = "cdrom-image"
 ide0:0.fileName = "/vmimages/tools-isoimages/linux.iso"
@@ -26,7 +26,7 @@ ide0:1.deviceType = "atapi-cdrom"
 ide0:1.fileName = "/dev/scd0"
 ide1:1.present = "true"
 ide1:1.deviceType = "ata-hardDisk"
-ide1:1.fileName = "Debian1-IDE.vmdk"
+ide1:1.fileName = "/vmfs/volumes/498076b2-02796c1a-ef5b-000ae484a6a3/virtDebian1/Debian1-IDE.vmdk"
 floppy0.present = "true"
 floppy0.fileType = "device"
 floppy0.fileName = "/dev/fd0"
index 62e8bb4ab4c4af5080b60a762ca5e0f515f91dcb..774b4414419dae970fe2f4cec4b1ddc28970e498 100644 (file)
   <devices>
     <disk type='file' device='disk'>
       <driver name='lsilogic' cache='writethrough'/>
-      <source file='Debian1.vmdk'/>
+      <source file='[498076b2-02796c1a-ef5b-000ae484a6a3] virtDebian1/Debian1.vmdk'/>
       <target dev='sda' bus='scsi'/>
     </disk>
     <disk type='file' device='cdrom'>
       <driver name='buslogic'/>
-      <source file='Debian1-cdrom.iso'/>
+      <source file='[498076b2-02796c1a-ef5b-000ae484a6a3] virtDebian1/Debian1-cdrom.iso'/>
       <target dev='sdp' bus='scsi'/>
     </disk>
     <disk type='file' device='cdrom'>
@@ -31,7 +31,7 @@
       <target dev='hdb' bus='ide'/>
     </disk>
     <disk type='file' device='disk'>
-      <source file='Debian1-IDE.vmdk'/>
+      <source file='[498076b2-02796c1a-ef5b-000ae484a6a3] virtDebian1/Debian1-IDE.vmdk'/>
       <target dev='hdd' bus='ide'/>
     </disk>
     <disk type='block' device='floppy'>
index c0bc514b8a0b4c3922b4cf66a7562008b408f42d..d418475bd22f78821db4fbb562b66ee792654238 100644 (file)
@@ -10,7 +10,7 @@ scsi0.present = "true"
 scsi0.virtualDev = "lsilogic"
 scsi0:0.present = "true"
 scsi0:0.deviceType = "scsi-hardDisk"
-scsi0:0.fileName = "Debian2.vmdk"
+scsi0:0.fileName = "/vmfs/volumes/498076b2-02796c1a-ef5b-000ae484a6a3/Debian2/Debian2.vmdk"
 ide0:0.present = "true"
 ide0:0.deviceType = "cdrom-image"
 ide0:0.fileName = "/vmfs/volumes/498076b2-02796c1a-ef5b-000ae484a6a3/Isos/debian-testing-amd64-netinst.iso"
index 3f85cb429b979abfdfb7ce49a094620716fa053e..c8719817ea726f71c3ed2a722f23c5c46b23bb28 100644 (file)
   <devices>
     <disk type='file' device='disk'>
       <driver name='lsilogic'/>
-      <source file='Debian2.vmdk'/>
+      <source file='[498076b2-02796c1a-ef5b-000ae484a6a3] Debian2/Debian2.vmdk'/>
       <target dev='sda' bus='scsi'/>
     </disk>
     <disk type='file' device='cdrom'>
-      <source file='/vmfs/volumes/498076b2-02796c1a-ef5b-000ae484a6a3/Isos/debian-testing-amd64-netinst.iso'/>
+      <source file='[498076b2-02796c1a-ef5b-000ae484a6a3] Isos/debian-testing-amd64-netinst.iso'/>
       <target dev='hda' bus='ide'/>
     </disk>
     <disk type='file' device='floppy'>
-      <source file='/vmfs/volumes/498076b2-02796c1a-ef5b-000ae484a6a3/Debian2/dummy.flp'/>
+      <source file='[498076b2-02796c1a-ef5b-000ae484a6a3] Debian2/dummy.flp'/>
       <target dev='fdb' bus='fdc'/>
     </disk>
     <interface type='bridge'>
index 8685bae583b1f5c6b077a31c07c4be39ab5a51e7..68f6d6d308f4409af8cc8e8d4acfd872d4790d0d 100644 (file)
@@ -9,17 +9,17 @@ scsi0.present = "true"
 scsi0.virtualDev = "lsilogic"
 scsi0:0.present = "true"
 scsi0:0.deviceType = "scsi-hardDisk"
-scsi0:0.fileName = "virtMonServ1.vmdk"
+scsi0:0.fileName = "/vmfs/volumes/498076b2-02796c1a-ef5b-000ae484a6a3/virtMonServ1/virtMonServ1.vmdk"
 ethernet0.present = "true"
 ethernet0.networkName = "VM Network"
 ethernet0.connectionType = "bridged"
-ethernet0.addressType = "static"
-ethernet0.address = "00:50:56:91:66:D4"
+ethernet0.addressType = "generated"
+ethernet0.generatedAddress = "00:50:56:91:66:D4"
 ethernet1.present = "true"
 ethernet1.networkName = "VM Switch 2"
 ethernet1.connectionType = "bridged"
-ethernet1.addressType = "static"
-ethernet1.address = "00:50:56:91:0C:51"
+ethernet1.addressType = "generated"
+ethernet1.generatedAddress = "00:50:56:91:0C:51"
 serial0.present = "true"
 serial0.fileType = "file"
 serial0.fileName = "/vmfs/volumes/498076b2-02796c1a-ef5b-000ae484a6a3/virtMonServ1/serial1.file"
index 2b3ed933629101da94f3bec01f49892e4272c406..078753a94f85c21eeef66c1c761192657bc9e228 100644 (file)
@@ -14,7 +14,7 @@
   <devices>
     <disk type='file' device='disk'>
       <driver name='lsilogic'/>
-      <source file='virtMonServ1.vmdk'/>
+      <source file='[498076b2-02796c1a-ef5b-000ae484a6a3] virtMonServ1/virtMonServ1.vmdk'/>
       <target dev='sda' bus='scsi'/>
     </disk>
     <interface type='bridge'>
       <source bridge='VM Switch 2'/>
     </interface>
     <serial type='file'>
-      <source path='/vmfs/volumes/498076b2-02796c1a-ef5b-000ae484a6a3/virtMonServ1/serial1.file'/>
+      <source path='[498076b2-02796c1a-ef5b-000ae484a6a3] virtMonServ1/serial1.file'/>
       <target port='0'/>
     </serial>
     <parallel type='file'>
-      <source path='/vmfs/volumes/498076b2-02796c1a-ef5b-000ae484a6a3/virtMonServ1/parallel1.file'/>
+      <source path='[498076b2-02796c1a-ef5b-000ae484a6a3] virtMonServ1/parallel1.file'/>
       <target port='0'/>
     </parallel>
     <console type='file'>
-      <source path='/vmfs/volumes/498076b2-02796c1a-ef5b-000ae484a6a3/virtMonServ1/serial1.file'/>
+      <source path='[498076b2-02796c1a-ef5b-000ae484a6a3] virtMonServ1/serial1.file'/>
       <target port='0'/>
     </console>
   </devices>
index 7d9c6f7a6ddb79b4f3fdd5f3d3bff5089ef9b23c..73ca8a85040408946028bc3de07bb7198ab8c211 100644 (file)
@@ -8,5 +8,5 @@ numvcpus = "1"
 ethernet0.present = "true"
 ethernet0.networkName = "VM Network"
 ethernet0.connectionType = "bridged"
-ethernet0.addressType = "static"
-ethernet0.address = "00:50:56:11:22:33"
+ethernet0.addressType = "generated"
+ethernet0.generatedAddress = "00:50:56:11:22:33"
index fb4b116f3f35a3b89ff82336cf7bf4b40dfc87c2..cc42140b1d54ea8924ff0cc40f6f54b2b8fac7f7 100644 (file)
@@ -9,5 +9,5 @@ ethernet0.present = "true"
 ethernet0.networkName = "VM Network"
 ethernet0.connectionType = "custom"
 ethernet0.vnet = "vmnet7"
-ethernet0.addressType = "static"
-ethernet0.address = "00:50:56:11:22:33"
+ethernet0.addressType = "generated"
+ethernet0.generatedAddress = "00:50:56:11:22:33"
index 3aed46cad4907f761b2b500c4716491e2a5ccada..dd2c86d93fa1d1da6daf0fbab30157a9654950df 100644 (file)
@@ -9,5 +9,5 @@ ethernet0.present = "true"
 ethernet0.virtualDev = "e1000"
 ethernet0.networkName = "VM Network"
 ethernet0.connectionType = "bridged"
-ethernet0.addressType = "static"
-ethernet0.address = "00:50:56:11:22:33"
+ethernet0.addressType = "generated"
+ethernet0.generatedAddress = "00:50:56:11:22:33"
index e3322392ab6baa7645680b03ab857c06e6e40eda..40b02c223bcce972b7676da10ffea81039f4f621 100644 (file)
@@ -7,4 +7,4 @@ memsize = "4"
 numvcpus = "1"
 floppy0.present = "true"
 floppy0.fileType = "file"
-floppy0.fileName = "floppy.flp"
+floppy0.fileName = "/vmfs/volumes/testing/floppy.flp"
index a069fda9270516e81739a09dbd3ee426b79bbc69..deff02e0682cc0e96c661b78d6b878c51862d898 100644 (file)
@@ -7,7 +7,7 @@
   </os>
   <devices>
     <disk type='file' device='floppy'>
-      <source file='floppy.flp'/>
+      <source file='[testing] floppy.flp'/>
       <target dev='fda' bus='fdc'/>
     </disk>
   </devices>
index a018d4f7419d3067eebc13a119f4ecd059ad9064..8b2d6a45bcaacf727831feac99c91ef33db1ec48 100644 (file)
@@ -7,7 +7,7 @@ memsize = "32"
 numvcpus = "1"
 ide0:0.present = "true"
 ide0:0.deviceType = "ata-hardDisk"
-ide0:0.fileName = "Debian-System1-0-cl2.vmdk"
+ide0:0.fileName = "/vmfs/volumes/storage/Server1/Debian-System1-0-cl2.vmdk"
 ethernet0.present = "true"
 ethernet0.networkName = "net1"
 ethernet0.connectionType = "custom"
index d2bc9641de6fd30341a9e41622bb38e6ee75a423..44e1c13d51e4b088dde063a1db4aef1a4ea6977c 100644 (file)
@@ -13,7 +13,7 @@
   <on_crash>destroy</on_crash>
   <devices>
     <disk type='file' device='disk'>
-      <source file='Debian-System1-0-cl2.vmdk'/>
+      <source file='[storage] Server1/Debian-System1-0-cl2.vmdk'/>
       <target dev='hda' bus='ide'/>
     </disk>
     <interface type='bridge'>
index 5c248a772f42e63a2e08ad78a706faa21b16f729..d811b7f754f3772400e26ada0005d7f50c7e1bed 100644 (file)
@@ -7,7 +7,7 @@ memsize = "32"
 numvcpus = "1"
 ide0:0.present = "true"
 ide0:0.deviceType = "ata-hardDisk"
-ide0:0.fileName = "Debian-System1-0-cl3.vmdk"
+ide0:0.fileName = "/vmfs/volumes/storage/Server2/Debian-System1-0-cl3.vmdk"
 ethernet0.present = "true"
 ethernet0.networkName = "net1"
 ethernet0.connectionType = "custom"
index 1e1bab8fd5341475e62fd1f21611a6c539e1b250..7c2a57d1501a6b185c0f22ac45b335b5642f3dd4 100644 (file)
@@ -13,7 +13,7 @@
   <on_crash>destroy</on_crash>
   <devices>
     <disk type='file' device='disk'>
-      <source file='Debian-System1-0-cl3.vmdk'/>
+      <source file='[storage] Server2/Debian-System1-0-cl3.vmdk'/>
       <target dev='hda' bus='ide'/>
     </disk>
     <interface type='bridge'>
index 865ebfc805b6ff763875dfb3219f95c505b0f7ba..7109fb9a142d63e86bc59d3245ddba3decbf4479 100644 (file)
@@ -7,7 +7,7 @@ memsize = "32"
 numvcpus = "1"
 ide0:0.present = "true"
 ide0:0.deviceType = "ata-hardDisk"
-ide0:0.fileName = "Debian-System1-0-cl1.vmdk"
+ide0:0.fileName = "/vmfs/volumes/storage/Router/Debian-System1-0-cl1.vmdk"
 ethernet0.present = "true"
 ethernet0.networkName = "net1"
 ethernet0.connectionType = "custom"
index 93ca7542b5748995073a8076bc07e2ce9e0446d7..49f023868172dd18c4458e493a7484d62c51c504 100644 (file)
@@ -13,7 +13,7 @@
   <on_crash>destroy</on_crash>
   <devices>
     <disk type='file' device='disk'>
-      <source file='Debian-System1-0-cl1.vmdk'/>
+      <source file='[storage] Router/Debian-System1-0-cl1.vmdk'/>
       <target dev='hda' bus='ide'/>
     </disk>
     <interface type='bridge'>
index 947154cb921594eee151499f6e95f63f2f552a1a..ee9b8c9f05477e27dd0aab57219a12bccc5c2995 100644 (file)
@@ -7,7 +7,7 @@ memsize = "264"
 numvcpus = "1"
 ide0:0.present = "true"
 ide0:0.deviceType = "ata-hardDisk"
-ide0:0.fileName = "Debian-System1-0-cl2.vmdk"
+ide0:0.fileName = "/vmfs/volumes/storage/Client/Debian-System1-0-cl2.vmdk"
 ethernet0.present = "true"
 ethernet0.networkName = "net2"
 ethernet0.connectionType = "custom"
index 99038838d50ee656707bf666b0f8fab0771e4b37..059c5241d6c6a2c7799c036eeaa0668ae86d923b 100644 (file)
@@ -13,7 +13,7 @@
   <on_crash>destroy</on_crash>
   <devices>
     <disk type='file' device='disk'>
-      <source file='Debian-System1-0-cl2.vmdk'/>
+      <source file='[storage] Client/Debian-System1-0-cl2.vmdk'/>
       <target dev='hda' bus='ide'/>
     </disk>
     <interface type='bridge'>
index 2ce1b12ac734891e7da7f2ef5f72e7fef794a339..cd969695989d4b7855987c2c4a1f80db532f6d64 100644 (file)
@@ -7,4 +7,4 @@ memsize = "4"
 numvcpus = "1"
 ide0:0.present = "true"
 ide0:0.deviceType = "ata-hardDisk"
-ide0:0.fileName = "harddisk.vmdk"
+ide0:0.fileName = "/vmfs/volumes/datastore/directory/harddisk.vmdk"
index 147a7e2fa0ed57c66be88f624bf289f178c8113d..f83ad0183f881e32d1272cde4a877d0ddd0717cf 100644 (file)
@@ -7,7 +7,7 @@
   </os>
   <devices>
     <disk type='file' device='disk'>
-      <source file='harddisk.vmdk'/>
+      <source file='[datastore] directory/harddisk.vmdk'/>
       <target dev='hda' bus='ide'/>
     </disk>
   </devices>
index 38ca686be9e30b7b0b1244086e131db92e3fd66c..a270dc425e2f7585a19b18b3ab4fb0e115ac6cb3 100644 (file)
@@ -8,4 +8,4 @@ numvcpus = "1"
 scsi0.present = "true"
 scsi0:0.present = "true"
 scsi0:0.deviceType = "scsi-hardDisk"
-scsi0:0.fileName = "harddisk.vmdk"
+scsi0:0.fileName = "/vmfs/volumes/datastore/directory/harddisk.vmdk"
index 38eb26d073b5f57d9a09fcae05e484a409fc29cf..63eeff7866ee669fd51930063feb7b538eb5f04a 100644 (file)
@@ -7,7 +7,7 @@
   </os>
   <devices>
     <disk type='file' device='disk'>
-      <source file='harddisk.vmdk'/>
+      <source file='[datastore] directory/harddisk.vmdk'/>
       <target dev='sda' bus='scsi'/>
     </disk>
   </devices>
index 4f42d26c20a69e5b79e283c1ec383c36e6b6107f..40871b6cadf8ff0660216d0852fd714ed754d3ee 100644 (file)
@@ -7,4 +7,4 @@ memsize = "4"
 numvcpus = "1"
 parallel0.present = "true"
 parallel0.fileType = "file"
-parallel0.fileName = "parallel0.file"
+parallel0.fileName = "/vmfs/volumes/datastore/directory/parallel0.file"
index 2c81cedaa5afd3b9c5e45e95a7bf35f119960060..69f5effa6cc0682a49b145dddacc5d68220296bb 100644 (file)
@@ -7,7 +7,7 @@
   </os>
   <devices>
     <parallel type='file'>
-      <source path='parallel0.file'/>
+      <source path='[datastore] directory/parallel0.file'/>
       <target port='0'/>
     </parallel>
   </devices>
index de5da89c73f75dba7e871dc57da8032a955d3528..2f98da3cc8a3ab6efee3a1bfee21da9a7858f941 100644 (file)
@@ -9,4 +9,4 @@ scsi0.present = "true"
 scsi0.virtualDev = "buslogic"
 scsi0:0.present = "true"
 scsi0:0.deviceType = "scsi-hardDisk"
-scsi0:0.fileName = "harddisk.vmdk"
+scsi0:0.fileName = "/vmfs/volumes/datastore/directory/harddisk.vmdk"
index cd72df1fc4a3b23959bf99b8f444bfa1605c963b..5d52c5461cd333032e5985bf185a7b0d7b211cd7 100644 (file)
@@ -8,7 +8,7 @@
   <devices>
     <disk type='file' device='disk'>
       <driver name='buslogic'/>
-      <source file='harddisk.vmdk'/>
+      <source file='[datastore] directory/harddisk.vmdk'/>
       <target dev='sda' bus='scsi'/>
     </disk>
   </devices>
index feb577bb7d3cf496dd2a97ed8af907749deed156..30f464a7ee454016ec4bdecffad1b1f732a8f811 100644 (file)
@@ -9,5 +9,5 @@ scsi0.present = "true"
 scsi0.virtualDev = "buslogic"
 scsi0:0.present = "true"
 scsi0:0.deviceType = "scsi-hardDisk"
-scsi0:0.fileName = "harddisk.vmdk"
+scsi0:0.fileName = "/vmfs/volumes/datastore/directory/harddisk.vmdk"
 scsi0:0.writeThrough = "true"
index 90a771973fdeeb654c45a93d0ea29205fb347200..cbf5924fe6690d97eee13fd9b01e538a8da31bc5 100644 (file)
@@ -8,7 +8,7 @@
   <devices>
     <disk type='file' device='disk'>
       <driver name='buslogic' cache='writethrough'/>
-      <source file='harddisk.vmdk'/>
+      <source file='[datastore] directory/harddisk.vmdk'/>
       <target dev='sda' bus='scsi'/>
     </disk>
   </devices>
index 481e054afb29e77143be2278f30cfa9caea4d9a5..e64463c0a44c567e53f594f531e430da8758ddf2 100644 (file)
@@ -7,5 +7,5 @@ memsize = "4"
 numvcpus = "1"
 serial0.present = "true"
 serial0.fileType = "file"
-serial0.fileName = "serial0.file"
+serial0.fileName = "/vmfs/volumes/datastore/directory/serial0.file"
 serial0.yieldOnMsrRead = "true"
index 6fc8eaccc62a860249f56e2c959d6c023ae42497..58a5a5ec08c6b4dc95b5ee61d12a1acb2f32c625 100644 (file)
@@ -7,7 +7,7 @@
   </os>
   <devices>
     <serial type='file'>
-      <source path='serial0.file'/>
+      <source path='[datastore] directory/serial0.file'/>
       <target port='0'/>
     </serial>
   </devices>
index df0a4a6b8ff4cb83734289f350092e0401a042e0..abf1f32bb98c29c60350e3a3006c81fb23732842 100644 (file)
@@ -89,7 +89,7 @@ testCompareFiles(const char *xml, const char *vmx, esxVI_APIVersion apiVersion)
         goto failure;
     }
 
-    formatted = esxVMX_FormatConfig(NULL, def, apiVersion);
+    formatted = esxVMX_FormatConfig(NULL, NULL, def, apiVersion);
 
     if (formatted == NULL) {
         goto failure;