From 885a161b62f985dd83c95f4524af4823cc261043 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Wed, 21 Aug 2013 17:32:51 -0700 Subject: [PATCH] CLOUDSTACK-4433:[VMware]Registration of template using the downloaded template URL is failing. --- .../manager/VmwareStorageManagerImpl.java | 958 +++++++++--------- .../resource/VmwareStorageProcessor.java | 7 +- 2 files changed, 491 insertions(+), 474 deletions(-) diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java index 985b30ec511..e7fbb042814 100644 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java @@ -54,9 +54,6 @@ import com.cloud.hypervisor.vmware.mo.DatastoreMO; import com.cloud.hypervisor.vmware.mo.HostDatastoreBrowserMO; import com.cloud.hypervisor.vmware.mo.HostMO; import com.cloud.hypervisor.vmware.mo.HypervisorHostHelper; -import com.cloud.hypervisor.vmware.mo.SnapshotDescriptor; -import com.cloud.hypervisor.vmware.mo.SnapshotDescriptor.SnapshotInfo; -import com.cloud.hypervisor.vmware.mo.TaskMO; import com.cloud.hypervisor.vmware.mo.VirtualMachineMO; import com.cloud.hypervisor.vmware.mo.VmwareHypervisorHost; import com.cloud.hypervisor.vmware.util.VmwareContext; @@ -78,7 +75,6 @@ import com.vmware.vim25.FileQueryFlags; import com.vmware.vim25.HostDatastoreBrowserSearchResults; import com.vmware.vim25.HostDatastoreBrowserSearchSpec; import com.vmware.vim25.ManagedObjectReference; -import com.vmware.vim25.TaskEvent; import com.vmware.vim25.TaskInfo; import com.vmware.vim25.VirtualDeviceConfigSpec; import com.vmware.vim25.VirtualDeviceConfigSpecOperation; @@ -229,139 +225,141 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { @Override public Answer execute(VmwareHostService hostService, PrimaryStorageDownloadCommand cmd) { - String secondaryStorageUrl = cmd.getSecondaryStorageUrl(); - assert (secondaryStorageUrl != null); + String secondaryStorageUrl = cmd.getSecondaryStorageUrl(); + assert (secondaryStorageUrl != null); - String templateUrl = cmd.getUrl(); + String templateUrl = cmd.getUrl(); - String templateName = null; - String mountPoint = null; - if (templateUrl.endsWith(".ova")) { - int index = templateUrl.lastIndexOf("/"); - mountPoint = templateUrl.substring(0, index); - mountPoint = mountPoint.substring(secondaryStorageUrl.length() + 1); - if (!mountPoint.endsWith("/")) { - mountPoint = mountPoint + "/"; - } + String templateName = null; + String mountPoint = null; + if (templateUrl.endsWith(".ova")) { + int index = templateUrl.lastIndexOf("/"); + mountPoint = templateUrl.substring(0, index); + mountPoint = mountPoint.substring(secondaryStorageUrl.length() + 1); + if (!mountPoint.endsWith("/")) { + mountPoint = mountPoint + "/"; + } - templateName = templateUrl.substring(index + 1).replace("." + ImageFormat.OVA.getFileExtension(), ""); + templateName = templateUrl.substring(index + 1).replace("." + ImageFormat.OVA.getFileExtension(), ""); - if (templateName == null || templateName.isEmpty()) { - templateName = cmd.getName(); - } - } else { - mountPoint = templateUrl.substring(secondaryStorageUrl.length() + 1); - if (!mountPoint.endsWith("/")) { - mountPoint = mountPoint + "/"; - } - templateName = cmd.getName(); - } + if (templateName == null || templateName.isEmpty()) { + templateName = cmd.getName(); + } + } else { + mountPoint = templateUrl.substring(secondaryStorageUrl.length() + 1); + if (!mountPoint.endsWith("/")) { + mountPoint = mountPoint + "/"; + } + templateName = cmd.getName(); + } - VmwareContext context = hostService.getServiceContext(cmd); - try { - VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, cmd); + VmwareContext context = hostService.getServiceContext(cmd); + try { + VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, cmd); - String templateUuidName = UUID.nameUUIDFromBytes((templateName + "@" + cmd.getPoolUuid() + "-" + hyperHost.getMor().getValue()).getBytes()).toString(); - // truncate template name to 32 chars to ensure they work well with vSphere API's. - templateUuidName = templateUuidName.replace("-", ""); + String templateUuidName = UUID.nameUUIDFromBytes((templateName + "@" + cmd.getPoolUuid() + "-" + hyperHost.getMor().getValue()).getBytes()).toString(); + // truncate template name to 32 chars to ensure they work well with vSphere API's. + templateUuidName = templateUuidName.replace("-", ""); - DatacenterMO dcMo = new DatacenterMO(context, hyperHost.getHyperHostDatacenter()); - VirtualMachineMO templateMo = VmwareHelper.pickOneVmOnRunningHost(dcMo.findVmByNameAndLabel(templateUuidName), true); + DatacenterMO dcMo = new DatacenterMO(context, hyperHost.getHyperHostDatacenter()); + VirtualMachineMO templateMo = VmwareHelper.pickOneVmOnRunningHost(dcMo.findVmByNameAndLabel(templateUuidName), true); - if (templateMo == null) { - if(s_logger.isInfoEnabled()) - s_logger.info("Template " + templateName + " is not setup yet, setup template from secondary storage with uuid name: " + templateUuidName); - ManagedObjectReference morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, cmd.getPoolUuid()); - assert (morDs != null); - DatastoreMO primaryStorageDatastoreMo = new DatastoreMO(context, morDs); + if (templateMo == null) { + if(s_logger.isInfoEnabled()) { + s_logger.info("Template " + templateName + " is not setup yet, setup template from secondary storage with uuid name: " + templateUuidName); + } + ManagedObjectReference morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, cmd.getPoolUuid()); + assert (morDs != null); + DatastoreMO primaryStorageDatastoreMo = new DatastoreMO(context, morDs); - copyTemplateFromSecondaryToPrimary(hyperHost, - primaryStorageDatastoreMo, secondaryStorageUrl, - mountPoint, templateName, templateUuidName); - } else { - s_logger.info("Template " + templateName + " has already been setup, skip the template setup process in primary storage"); - } + copyTemplateFromSecondaryToPrimary(hyperHost, + primaryStorageDatastoreMo, secondaryStorageUrl, + mountPoint, templateName, templateUuidName); + } else { + s_logger.info("Template " + templateName + " has already been setup, skip the template setup process in primary storage"); + } - return new PrimaryStorageDownloadAnswer(templateUuidName, 0); - } catch (Throwable e) { - if (e instanceof RemoteException) { - hostService.invalidateServiceContext(context); - } + return new PrimaryStorageDownloadAnswer(templateUuidName, 0); + } catch (Throwable e) { + if (e instanceof RemoteException) { + hostService.invalidateServiceContext(context); + } - String msg = "Unable to execute PrimaryStorageDownloadCommand due to exception"; - s_logger.error(msg, e); - return new PrimaryStorageDownloadAnswer(msg); - } + String msg = "Unable to execute PrimaryStorageDownloadCommand due to exception"; + s_logger.error(msg, e); + return new PrimaryStorageDownloadAnswer(msg); + } } @Override - public Answer execute(VmwareHostService hostService, BackupSnapshotCommand cmd) { - Long accountId = cmd.getAccountId(); - Long volumeId = cmd.getVolumeId(); + public Answer execute(VmwareHostService hostService, BackupSnapshotCommand cmd) { + Long accountId = cmd.getAccountId(); + Long volumeId = cmd.getVolumeId(); String secondaryStorageUrl = cmd.getSecondaryStorageUrl(); String snapshotUuid = cmd.getSnapshotUuid(); // not null: Precondition. - String prevSnapshotUuid = cmd.getPrevSnapshotUuid(); - String prevBackupUuid = cmd.getPrevBackupUuid(); + String prevSnapshotUuid = cmd.getPrevSnapshotUuid(); + String prevBackupUuid = cmd.getPrevBackupUuid(); VirtualMachineMO workerVm=null; String workerVMName = null; - String volumePath = cmd.getVolumePath(); - ManagedObjectReference morDs = null; - DatastoreMO dsMo=null; + String volumePath = cmd.getVolumePath(); + ManagedObjectReference morDs = null; + DatastoreMO dsMo=null; - // By default assume failure - String details = null; - boolean success = false; - String snapshotBackupUuid = null; + // By default assume failure + String details = null; + boolean success = false; + String snapshotBackupUuid = null; - VmwareContext context = hostService.getServiceContext(cmd); - VirtualMachineMO vmMo = null; - try { - VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, cmd); - morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, cmd.getPool().getUuid()); + VmwareContext context = hostService.getServiceContext(cmd); + VirtualMachineMO vmMo = null; + try { + VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, cmd); + morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, cmd.getPool().getUuid()); - try { - vmMo = hyperHost.findVmOnHyperHost(cmd.getVmName()); - if (vmMo == null) { - if(s_logger.isDebugEnabled()) - s_logger.debug("Unable to find owner VM for BackupSnapshotCommand on host " + hyperHost.getHyperHostName() + ", will try within datacenter"); + try { + vmMo = hyperHost.findVmOnHyperHost(cmd.getVmName()); + if (vmMo == null) { + if(s_logger.isDebugEnabled()) { + s_logger.debug("Unable to find owner VM for BackupSnapshotCommand on host " + hyperHost.getHyperHostName() + ", will try within datacenter"); + } - vmMo = hyperHost.findVmOnPeerHyperHost(cmd.getVmName()); - if(vmMo == null) { - dsMo = new DatastoreMO(hyperHost.getContext(), morDs); + vmMo = hyperHost.findVmOnPeerHyperHost(cmd.getVmName()); + if(vmMo == null) { + dsMo = new DatastoreMO(hyperHost.getContext(), morDs); - workerVMName = hostService.getWorkerName(context, cmd, 0); + workerVMName = hostService.getWorkerName(context, cmd, 0); - // attach a volume to dummay wrapper VM for taking snapshot and exporting the VM for backup - if (!hyperHost.createBlankVm(workerVMName, null, 1, 512, 0, false, 4, 0, VirtualMachineGuestOsIdentifier.OTHER_GUEST.value(), morDs, false)) { - String msg = "Unable to create worker VM to execute BackupSnapshotCommand"; - s_logger.error(msg); - throw new Exception(msg); - } - vmMo = hyperHost.findVmOnHyperHost(workerVMName); - if (vmMo == null) { - throw new Exception("Failed to find the newly create or relocated VM. vmName: " + workerVMName); - } - workerVm = vmMo; + // attach a volume to dummay wrapper VM for taking snapshot and exporting the VM for backup + if (!hyperHost.createBlankVm(workerVMName, null, 1, 512, 0, false, 4, 0, VirtualMachineGuestOsIdentifier.OTHER_GUEST.value(), morDs, false)) { + String msg = "Unable to create worker VM to execute BackupSnapshotCommand"; + s_logger.error(msg); + throw new Exception(msg); + } + vmMo = hyperHost.findVmOnHyperHost(workerVMName); + if (vmMo == null) { + throw new Exception("Failed to find the newly create or relocated VM. vmName: " + workerVMName); + } + workerVm = vmMo; - // attach volume to worker VM + // attach volume to worker VM String datastoreVolumePath = getVolumePathInDatastore(dsMo, volumePath + ".vmdk"); - vmMo.attachDisk(new String[] { datastoreVolumePath }, morDs); - } - } + vmMo.attachDisk(new String[] { datastoreVolumePath }, morDs); + } + } if (!vmMo.createSnapshot(snapshotUuid, "Snapshot taken for " + cmd.getSnapshotName(), false, false)) { throw new Exception("Failed to take snapshot " + cmd.getSnapshotName() + " on vm: " + cmd.getVmName()); } - snapshotBackupUuid = backupSnapshotToSecondaryStorage(vmMo, accountId, volumeId, cmd.getVolumePath(), snapshotUuid, secondaryStorageUrl, prevSnapshotUuid, prevBackupUuid, - hostService.getWorkerName(context, cmd, 1)); + snapshotBackupUuid = backupSnapshotToSecondaryStorage(vmMo, accountId, volumeId, cmd.getVolumePath(), snapshotUuid, secondaryStorageUrl, prevSnapshotUuid, prevBackupUuid, + hostService.getWorkerName(context, cmd, 1)); success = (snapshotBackupUuid != null); if (success) { details = "Successfully backedUp the snapshotUuid: " + snapshotUuid + " to secondary storage."; } - } finally { + } finally { if(vmMo != null){ ManagedObjectReference snapshotMor = vmMo.getSnapshotMor(snapshotUuid); if (snapshotMor != null){ @@ -369,214 +367,215 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { } } - try { - if (workerVm != null) { - // detach volume and destroy worker vm - workerVm.detachAllDisks(); - workerVm.destroy(); - } - } catch (Throwable e) { - s_logger.warn("Failed to destroy worker VM: " + workerVMName); - } - } - } catch (Throwable e) { - if (e instanceof RemoteException) { - hostService.invalidateServiceContext(context); - } + try { + if (workerVm != null) { + // detach volume and destroy worker vm + workerVm.detachAllDisks(); + workerVm.destroy(); + } + } catch (Throwable e) { + s_logger.warn("Failed to destroy worker VM: " + workerVMName); + } + } + } catch (Throwable e) { + if (e instanceof RemoteException) { + hostService.invalidateServiceContext(context); + } - s_logger.error("Unexpecpted exception ", e); + s_logger.error("Unexpecpted exception ", e); - details = "BackupSnapshotCommand exception: " + StringUtils.getExceptionStackInfo(e); - return new BackupSnapshotAnswer(cmd, false, details, snapshotBackupUuid, true); - } + details = "BackupSnapshotCommand exception: " + StringUtils.getExceptionStackInfo(e); + return new BackupSnapshotAnswer(cmd, false, details, snapshotBackupUuid, true); + } - return new BackupSnapshotAnswer(cmd, success, details, snapshotBackupUuid, true); - } + return new BackupSnapshotAnswer(cmd, success, details, snapshotBackupUuid, true); + } @Override - public Answer execute(VmwareHostService hostService, CreatePrivateTemplateFromVolumeCommand cmd) { + public Answer execute(VmwareHostService hostService, CreatePrivateTemplateFromVolumeCommand cmd) { String secondaryStoragePoolURL = cmd.getSecondaryStorageUrl(); - String volumePath = cmd.getVolumePath(); - Long accountId = cmd.getAccountId(); - Long templateId = cmd.getTemplateId(); - String details = null; + String volumePath = cmd.getVolumePath(); + Long accountId = cmd.getAccountId(); + Long templateId = cmd.getTemplateId(); + String details = null; - VmwareContext context = hostService.getServiceContext(cmd); - try { - VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, cmd); + VmwareContext context = hostService.getServiceContext(cmd); + try { + VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, cmd); - VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(cmd.getVmName()); - if (vmMo == null) { - if(s_logger.isDebugEnabled()) - s_logger.debug("Unable to find the owner VM for CreatePrivateTemplateFromVolumeCommand on host " + hyperHost.getHyperHostName() + ", try within datacenter"); - vmMo = hyperHost.findVmOnPeerHyperHost(cmd.getVmName()); + VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(cmd.getVmName()); + if (vmMo == null) { + if(s_logger.isDebugEnabled()) { + s_logger.debug("Unable to find the owner VM for CreatePrivateTemplateFromVolumeCommand on host " + hyperHost.getHyperHostName() + ", try within datacenter"); + } + vmMo = hyperHost.findVmOnPeerHyperHost(cmd.getVmName()); - if(vmMo == null) { - String msg = "Unable to find the owner VM for volume operation. vm: " + cmd.getVmName(); - s_logger.error(msg); - throw new Exception(msg); - } - } + if(vmMo == null) { + String msg = "Unable to find the owner VM for volume operation. vm: " + cmd.getVmName(); + s_logger.error(msg); + throw new Exception(msg); + } + } - Ternary result = createTemplateFromVolume(vmMo, - accountId, templateId, cmd.getUniqueName(), - secondaryStoragePoolURL, volumePath, - hostService.getWorkerName(context, cmd, 0)); + Ternary result = createTemplateFromVolume(vmMo, + accountId, templateId, cmd.getUniqueName(), + secondaryStoragePoolURL, volumePath, + hostService.getWorkerName(context, cmd, 0)); - return new CreatePrivateTemplateAnswer(cmd, true, null, - result.first(), result.third(), result.second(), - cmd.getUniqueName(), ImageFormat.OVA); + return new CreatePrivateTemplateAnswer(cmd, true, null, + result.first(), result.third(), result.second(), + cmd.getUniqueName(), ImageFormat.OVA); - } catch (Throwable e) { - if (e instanceof RemoteException) { - hostService.invalidateServiceContext(context); - } + } catch (Throwable e) { + if (e instanceof RemoteException) { + hostService.invalidateServiceContext(context); + } - s_logger.error("Unexpecpted exception ", e); + s_logger.error("Unexpecpted exception ", e); - details = "CreatePrivateTemplateFromVolumeCommand exception: " + StringUtils.getExceptionStackInfo(e); - return new CreatePrivateTemplateAnswer(cmd, false, details); - } - } + details = "CreatePrivateTemplateFromVolumeCommand exception: " + StringUtils.getExceptionStackInfo(e); + return new CreatePrivateTemplateAnswer(cmd, false, details); + } + } @Override - public Answer execute(VmwareHostService hostService, CreatePrivateTemplateFromSnapshotCommand cmd) { - Long accountId = cmd.getAccountId(); - Long volumeId = cmd.getVolumeId(); + public Answer execute(VmwareHostService hostService, CreatePrivateTemplateFromSnapshotCommand cmd) { + Long accountId = cmd.getAccountId(); + Long volumeId = cmd.getVolumeId(); String secondaryStorageUrl = cmd.getSecondaryStorageUrl(); - String backedUpSnapshotUuid = cmd.getSnapshotUuid(); - Long newTemplateId = cmd.getNewTemplateId(); - String details; - String uniqeName = UUID.randomUUID().toString(); + String backedUpSnapshotUuid = cmd.getSnapshotUuid(); + Long newTemplateId = cmd.getNewTemplateId(); + String details; + String uniqeName = UUID.randomUUID().toString(); - VmwareContext context = hostService.getServiceContext(cmd); - try { - Ternary result = createTemplateFromSnapshot(accountId, - newTemplateId, uniqeName, - secondaryStorageUrl, volumeId, - backedUpSnapshotUuid); + VmwareContext context = hostService.getServiceContext(cmd); + try { + Ternary result = createTemplateFromSnapshot(accountId, + newTemplateId, uniqeName, + secondaryStorageUrl, volumeId, + backedUpSnapshotUuid); - return new CreatePrivateTemplateAnswer(cmd, true, null, - result.first(), result.third(), result.second(), - uniqeName, ImageFormat.OVA); - } catch (Throwable e) { - if (e instanceof RemoteException) { - hostService.invalidateServiceContext(context); - } + return new CreatePrivateTemplateAnswer(cmd, true, null, + result.first(), result.third(), result.second(), + uniqeName, ImageFormat.OVA); + } catch (Throwable e) { + if (e instanceof RemoteException) { + hostService.invalidateServiceContext(context); + } - s_logger.error("Unexpecpted exception ", e); + s_logger.error("Unexpecpted exception ", e); - details = "CreatePrivateTemplateFromSnapshotCommand exception: " + StringUtils.getExceptionStackInfo(e); - return new CreatePrivateTemplateAnswer(cmd, false, details); - } - } + details = "CreatePrivateTemplateFromSnapshotCommand exception: " + StringUtils.getExceptionStackInfo(e); + return new CreatePrivateTemplateAnswer(cmd, false, details); + } + } @Override - public Answer execute(VmwareHostService hostService, CopyVolumeCommand cmd) { - Long volumeId = cmd.getVolumeId(); - String volumePath = cmd.getVolumePath(); - String secondaryStorageURL = cmd.getSecondaryStorageURL(); - String vmName = cmd.getVmName(); + public Answer execute(VmwareHostService hostService, CopyVolumeCommand cmd) { + Long volumeId = cmd.getVolumeId(); + String volumePath = cmd.getVolumePath(); + String secondaryStorageURL = cmd.getSecondaryStorageURL(); + String vmName = cmd.getVmName(); - VmwareContext context = hostService.getServiceContext(cmd); - try { - VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, cmd); + VmwareContext context = hostService.getServiceContext(cmd); + try { + VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, cmd); - Pair result; - if (cmd.toSecondaryStorage()) { - result = copyVolumeToSecStorage(hostService, - hyperHost, cmd, vmName, volumeId, cmd.getPool().getUuid(), volumePath, - secondaryStorageURL, - hostService.getWorkerName(context, cmd, 0)); - } else { - StorageFilerTO poolTO = cmd.getPool(); + Pair result; + if (cmd.toSecondaryStorage()) { + result = copyVolumeToSecStorage(hostService, + hyperHost, cmd, vmName, volumeId, cmd.getPool().getUuid(), volumePath, + secondaryStorageURL, + hostService.getWorkerName(context, cmd, 0)); + } else { + StorageFilerTO poolTO = cmd.getPool(); - ManagedObjectReference morDatastore = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, poolTO.getUuid()); - if (morDatastore == null) { - morDatastore = hyperHost.mountDatastore( - false, - poolTO.getHost(), 0, poolTO.getPath(), - poolTO.getUuid().replace("-", "")); + ManagedObjectReference morDatastore = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, poolTO.getUuid()); + if (morDatastore == null) { + morDatastore = hyperHost.mountDatastore( + false, + poolTO.getHost(), 0, poolTO.getPath(), + poolTO.getUuid().replace("-", "")); - if (morDatastore == null) { - throw new Exception("Unable to mount storage pool on host. storeUrl: " + poolTO.getHost() + ":/" + poolTO.getPath()); - } - } + if (morDatastore == null) { + throw new Exception("Unable to mount storage pool on host. storeUrl: " + poolTO.getHost() + ":/" + poolTO.getPath()); + } + } - result = copyVolumeFromSecStorage( - hyperHost, volumeId, - new DatastoreMO(context, morDatastore), - secondaryStorageURL, volumePath); - deleteVolumeDirOnSecondaryStorage(volumeId, secondaryStorageURL); - } - return new CopyVolumeAnswer(cmd, true, null, result.first(), result.second()); - } catch (Throwable e) { - if (e instanceof RemoteException) { - hostService.invalidateServiceContext(context); - } + result = copyVolumeFromSecStorage( + hyperHost, volumeId, + new DatastoreMO(context, morDatastore), + secondaryStorageURL, volumePath); + deleteVolumeDirOnSecondaryStorage(volumeId, secondaryStorageURL); + } + return new CopyVolumeAnswer(cmd, true, null, result.first(), result.second()); + } catch (Throwable e) { + if (e instanceof RemoteException) { + hostService.invalidateServiceContext(context); + } - String msg = "Unable to execute CopyVolumeCommand due to exception"; - s_logger.error(msg, e); - return new CopyVolumeAnswer(cmd, false, "CopyVolumeCommand failed due to exception: " + StringUtils.getExceptionStackInfo(e), null, null); - } - } + String msg = "Unable to execute CopyVolumeCommand due to exception"; + s_logger.error(msg, e); + return new CopyVolumeAnswer(cmd, false, "CopyVolumeCommand failed due to exception: " + StringUtils.getExceptionStackInfo(e), null, null); + } + } @Override - public Answer execute(VmwareHostService hostService, CreateVolumeFromSnapshotCommand cmd) { + public Answer execute(VmwareHostService hostService, CreateVolumeFromSnapshotCommand cmd) { - String primaryStorageNameLabel = cmd.getPrimaryStoragePoolNameLabel(); - Long accountId = cmd.getAccountId(); - Long volumeId = cmd.getVolumeId(); + String primaryStorageNameLabel = cmd.getPrimaryStoragePoolNameLabel(); + Long accountId = cmd.getAccountId(); + Long volumeId = cmd.getVolumeId(); String secondaryStorageUrl = cmd.getSecondaryStorageUrl(); - String backedUpSnapshotUuid = cmd.getSnapshotUuid(); + String backedUpSnapshotUuid = cmd.getSnapshotUuid(); - String details = null; - boolean success = false; - String newVolumeName = UUID.randomUUID().toString().replaceAll("-", ""); + String details = null; + boolean success = false; + String newVolumeName = UUID.randomUUID().toString().replaceAll("-", ""); - VmwareContext context = hostService.getServiceContext(cmd); - try { - VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, cmd); - ManagedObjectReference morPrimaryDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, - primaryStorageNameLabel); - if (morPrimaryDs == null) { - String msg = "Unable to find datastore: " + primaryStorageNameLabel; - s_logger.error(msg); - throw new Exception(msg); - } + VmwareContext context = hostService.getServiceContext(cmd); + try { + VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, cmd); + ManagedObjectReference morPrimaryDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, + primaryStorageNameLabel); + if (morPrimaryDs == null) { + String msg = "Unable to find datastore: " + primaryStorageNameLabel; + s_logger.error(msg); + throw new Exception(msg); + } - DatastoreMO primaryDsMo = new DatastoreMO(hyperHost.getContext(), morPrimaryDs); - details = createVolumeFromSnapshot(hyperHost, primaryDsMo, - newVolumeName, accountId, volumeId, secondaryStorageUrl, backedUpSnapshotUuid); - if (details == null) { - success = true; - } - } catch (Throwable e) { - if (e instanceof RemoteException) { - hostService.invalidateServiceContext(context); - } + DatastoreMO primaryDsMo = new DatastoreMO(hyperHost.getContext(), morPrimaryDs); + details = createVolumeFromSnapshot(hyperHost, primaryDsMo, + newVolumeName, accountId, volumeId, secondaryStorageUrl, backedUpSnapshotUuid); + if (details == null) { + success = true; + } + } catch (Throwable e) { + if (e instanceof RemoteException) { + hostService.invalidateServiceContext(context); + } - s_logger.error("Unexpecpted exception ", e); - details = "CreateVolumeFromSnapshotCommand exception: " + StringUtils.getExceptionStackInfo(e); - } + s_logger.error("Unexpecpted exception ", e); + details = "CreateVolumeFromSnapshotCommand exception: " + StringUtils.getExceptionStackInfo(e); + } - return new CreateVolumeFromSnapshotAnswer(cmd, success, details, newVolumeName); - } + return new CreateVolumeFromSnapshotAnswer(cmd, success, details, newVolumeName); + } // templateName: name in secondary storage // templateUuid: will be used at hypervisor layer private void copyTemplateFromSecondaryToPrimary(VmwareHypervisorHost hyperHost, DatastoreMO datastoreMo, String secondaryStorageUrl, - String templatePathAtSecondaryStorage, String templateName, String templateUuid) throws Exception { + String templatePathAtSecondaryStorage, String templateName, String templateUuid) throws Exception { s_logger.info("Executing copyTemplateFromSecondaryToPrimary. secondaryStorage: " - + secondaryStorageUrl + ", templatePathAtSecondaryStorage: " + templatePathAtSecondaryStorage - + ", templateName: " + templateName); + + secondaryStorageUrl + ", templatePathAtSecondaryStorage: " + templatePathAtSecondaryStorage + + ", templateName: " + templateName); String secondaryMountPoint = _mountService.getMountPoint(secondaryStorageUrl); s_logger.info("Secondary storage mount point: " + secondaryMountPoint); String srcOVAFileName = secondaryMountPoint + "/" + templatePathAtSecondaryStorage + - templateName + "." + ImageFormat.OVA.getFileExtension(); + templateName + "." + ImageFormat.OVA.getFileExtension(); String srcFileName = getOVFFilePath(srcOVAFileName); if(srcFileName == null) { @@ -606,8 +605,8 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(vmName); if(vmMo == null) { String msg = "Failed to import OVA template. secondaryStorage: " - + secondaryStorageUrl + ", templatePathAtSecondaryStorage: " + templatePathAtSecondaryStorage - + ", templateName: " + templateName + ", templateUuid: " + templateUuid; + + secondaryStorageUrl + ", templatePathAtSecondaryStorage: " + templatePathAtSecondaryStorage + + ", templateName: " + templateName + ", templateUuid: " + templateUuid; s_logger.error(msg); throw new Exception(msg); } @@ -624,7 +623,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { } private Ternary createTemplateFromVolume(VirtualMachineMO vmMo, long accountId, long templateId, String templateUniqueName, - String secStorageUrl, String volumePath, String workerVmName) throws Exception { + String secStorageUrl, String volumePath, String workerVmName) throws Exception { String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl); String installPath = getTemplateRelativeDirInSecStorage(accountId, templateId); @@ -637,7 +636,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { String result = command.execute(); if(result != null) { String msg = "unable to prepare template directory: " - + installPath + ", storage: " + secStorageUrl + ", error msg: " + result; + + installPath + ", storage: " + secStorageUrl + ", error msg: " + result; s_logger.error(msg); throw new Exception(msg); } @@ -660,7 +659,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { // 4 MB is the minimum requirement for VM memory in VMware vmMo.cloneFromCurrentSnapshot(workerVmName, 0, 4, volumeDeviceInfo.second(), - VmwareHelper.getDiskDeviceDatastore(volumeDeviceInfo.first())); + VmwareHelper.getDiskDeviceDatastore(volumeDeviceInfo.first())); clonedVm = vmMo.getRunningHost().findVmOnHyperHost(workerVmName); if(clonedVm == null) { String msg = "Unable to create dummy VM to export volume. volume path: " + volumePath; @@ -691,7 +690,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { } private Ternary createTemplateFromSnapshot(long accountId, long templateId, String templateUniqueName, - String secStorageUrl, long volumeId, String backedUpSnapshotUuid) throws Exception { + String secStorageUrl, long volumeId, String backedUpSnapshotUuid) throws Exception { String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl); String installPath = getTemplateRelativeDirInSecStorage(accountId, templateId); @@ -716,7 +715,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { result = command.execute(); if(result != null) { String msg = "unable to prepare template directory: " - + installPath + ", storage: " + secStorageUrl + ", error msg: " + result; + + installPath + ", storage: " + secStorageUrl + ", error msg: " + result; s_logger.error(msg); throw new Exception(msg); } @@ -729,9 +728,9 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { command.add(installFullOVAName); result = command.execute(); if(result != null) { - String msg = "unable to copy snapshot " + snapshotFullOVAName + " to " + installFullPath; - s_logger.error(msg); - throw new Exception(msg); + String msg = "unable to copy snapshot " + snapshotFullOVAName + " to " + installFullPath; + s_logger.error(msg); + throw new Exception(msg); } // untar OVA file at template directory @@ -742,40 +741,40 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { s_logger.info("Executing command: " + command.toString()); result = command.execute(); if(result != null) { - String msg = "unable to untar snapshot " + snapshotFullOVAName + " to " - + installFullPath; - s_logger.error(msg); - throw new Exception(msg); + String msg = "unable to untar snapshot " + snapshotFullOVAName + " to " + + installFullPath; + s_logger.error(msg); + throw new Exception(msg); } } else { // there is no ova file, only ovf originally; if(new File(snapshotFullOvfName).exists()) { - command = new Script(false, "cp", _timeout, s_logger); - command.add(snapshotFullOvfName); - //command.add(installFullOvfName); - command.add(installFullPath); - result = command.execute(); - if(result != null) { + command = new Script(false, "cp", _timeout, s_logger); + command.add(snapshotFullOvfName); + //command.add(installFullOvfName); + command.add(installFullPath); + result = command.execute(); + if(result != null) { String msg = "unable to copy snapshot " + snapshotFullOvfName + " to " + installFullPath; s_logger.error(msg); throw new Exception(msg); - } + } - s_logger.info("vmdkfile parent dir: " + snapshotFullVMDKName); - File snapshotdir = new File(snapshotFullVMDKName); - // File snapshotdir = new File(snapshotRoot); - File[] ssfiles = snapshotdir.listFiles(); - // List filenames = new ArrayList(); - for (int i = 0; i < ssfiles.length; i++) { - String vmdkfile = ssfiles[i].getName(); - s_logger.info("vmdk file name: " + vmdkfile); - if(vmdkfile.toLowerCase().startsWith(backupSSUuid) && vmdkfile.toLowerCase().endsWith(".vmdk")) { - snapshotFullVMDKName += vmdkfile; - templateVMDKName += vmdkfile; - break; - } - } - if (snapshotFullVMDKName != null) { + s_logger.info("vmdkfile parent dir: " + snapshotFullVMDKName); + File snapshotdir = new File(snapshotFullVMDKName); + // File snapshotdir = new File(snapshotRoot); + File[] ssfiles = snapshotdir.listFiles(); + // List filenames = new ArrayList(); + for (int i = 0; i < ssfiles.length; i++) { + String vmdkfile = ssfiles[i].getName(); + s_logger.info("vmdk file name: " + vmdkfile); + if(vmdkfile.toLowerCase().startsWith(backupSSUuid) && vmdkfile.toLowerCase().endsWith(".vmdk")) { + snapshotFullVMDKName += vmdkfile; + templateVMDKName += vmdkfile; + break; + } + } + if (snapshotFullVMDKName != null) { command = new Script(false, "cp", _timeout, s_logger); command.add(snapshotFullVMDKName); command.add(installFullPath); @@ -786,17 +785,17 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { s_logger.error(msg); throw new Exception(msg); } - } - } else { - String msg = "unable to find any snapshot ova/ovf files" + snapshotFullOVAName + " to " + installFullPath; - s_logger.error(msg); - throw new Exception(msg); - } + } + } else { + String msg = "unable to find any snapshot ova/ovf files" + snapshotFullOVAName + " to " + installFullPath; + s_logger.error(msg); + throw new Exception(msg); + } } long physicalSize = new File(installFullPath + "/" + templateVMDKName).length(); VmdkProcessor processor = new VmdkProcessor(); - // long physicalSize = new File(installFullPath + "/" + templateUniqueName + ".ova").length(); + // long physicalSize = new File(installFullPath + "/" + templateUniqueName + ".ova").length(); Map params = new HashMap(); params.put(StorageLayer.InstanceConfigKey, _storage); processor.configure("VMDK Processor", params); @@ -812,7 +811,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { } private void postCreatePrivateTemplate(String installFullPath, long templateId, - String templateName, long size, long virtualSize) throws Exception { + String templateName, long size, long virtualSize) throws Exception { // TODO a bit ugly here BufferedWriter out = null; @@ -846,50 +845,52 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { out.write("ova.size=" + size); out.newLine(); } finally { - if(out != null) + if(out != null) { out.close(); + } } } private void writeMetaOvaForTemplate(String installFullPath, String ovfFilename, String vmdkFilename, String templateName, long diskSize) throws Exception { - // TODO a bit ugly here - BufferedWriter out = null; - try { - out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(installFullPath + "/" + templateName +".ova.meta"))); - out.write("ova.filename=" + templateName + ".ova"); - out.newLine(); - out.write("version=1.0"); - out.newLine(); - out.write("ovf=" + ovfFilename); - out.newLine(); - out.write("numDisks=1"); - out.newLine(); - out.write("disk1.name=" + vmdkFilename); - out.newLine(); - out.write("disk1.size=" + diskSize); - out.newLine(); - } finally { - if(out != null) - out.close(); + // TODO a bit ugly here + BufferedWriter out = null; + try { + out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(installFullPath + "/" + templateName +".ova.meta"))); + out.write("ova.filename=" + templateName + ".ova"); + out.newLine(); + out.write("version=1.0"); + out.newLine(); + out.write("ovf=" + ovfFilename); + out.newLine(); + out.write("numDisks=1"); + out.newLine(); + out.write("disk1.name=" + vmdkFilename); + out.newLine(); + out.write("disk1.size=" + diskSize); + out.newLine(); + } finally { + if(out != null) { + out.close(); } - } + } + } private String createVolumeFromSnapshot(VmwareHypervisorHost hyperHost, DatastoreMO primaryDsMo, String newVolumeName, - long accountId, long volumeId, String secStorageUrl, String snapshotBackupUuid) throws Exception { + long accountId, long volumeId, String secStorageUrl, String snapshotBackupUuid) throws Exception { restoreVolumeFromSecStorage(hyperHost, primaryDsMo, newVolumeName, - secStorageUrl, getSnapshotRelativeDirInSecStorage(accountId, volumeId), snapshotBackupUuid); + secStorageUrl, getSnapshotRelativeDirInSecStorage(accountId, volumeId), snapshotBackupUuid); return null; } private void restoreVolumeFromSecStorage(VmwareHypervisorHost hyperHost, DatastoreMO primaryDsMo, String newVolumeName, - String secStorageUrl, String secStorageDir, String backupName) throws Exception { + String secStorageUrl, String secStorageDir, String backupName) throws Exception { String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl); String srcOVAFileName = secondaryMountPoint + "/" + secStorageDir + "/" - + backupName + "." + ImageFormat.OVA.getFileExtension(); + + backupName + "." + ImageFormat.OVA.getFileExtension(); String snapshotDir = ""; if (backupName.contains("/")){ snapshotDir = backupName.split("/")[0]; @@ -910,17 +911,17 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { s_logger.info("Executing command: " + command.toString()); String result = command.execute(); if(result != null) { - String msg = "Unable to unpack snapshot OVA file at: " + srcOVAFileName; - s_logger.error(msg); - throw new Exception(msg); + String msg = "Unable to unpack snapshot OVA file at: " + srcOVAFileName; + s_logger.error(msg); + throw new Exception(msg); } } else { - String msg = "Unable to find snapshot OVA file at: " + srcOVAFileName; - s_logger.error(msg); - throw new Exception(msg); - } + String msg = "Unable to find snapshot OVA file at: " + srcOVAFileName; + s_logger.error(msg); + throw new Exception(msg); + } - srcOVFFileName = getOVFFilePath(srcOVAFileName); + srcOVFFileName = getOVFFilePath(srcOVAFileName); } if(srcOVFFileName == null) { String msg = "Unable to locate OVF file in template package directory: " + srcOVAFileName; @@ -932,8 +933,9 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { try { hyperHost.importVmFromOVF(srcOVFFileName, newVolumeName, primaryDsMo, "thin"); clonedVm = hyperHost.findVmOnHyperHost(newVolumeName); - if(clonedVm == null) + if(clonedVm == null) { throw new Exception("Unable to create container VM for volume creation"); + } clonedVm.moveAllVmDiskFiles(primaryDsMo, "", false); clonedVm.detachAllDisks(); @@ -946,29 +948,30 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { } private String backupSnapshotToSecondaryStorage(VirtualMachineMO vmMo, long accountId, long volumeId, - String volumePath, String snapshotUuid, String secStorageUrl, - String prevSnapshotUuid, String prevBackupUuid, String workerVmName) throws Exception { + String volumePath, String snapshotUuid, String secStorageUrl, + String prevSnapshotUuid, String prevBackupUuid, String workerVmName) throws Exception { String backupUuid = UUID.randomUUID().toString(); exportVolumeToSecondaryStroage(vmMo, volumePath, secStorageUrl, - getSnapshotRelativeDirInSecStorage(accountId, volumeId), backupUuid, workerVmName); + getSnapshotRelativeDirInSecStorage(accountId, volumeId), backupUuid, workerVmName); return backupUuid + "/" + backupUuid; } private void exportVolumeToSecondaryStroage(VirtualMachineMO vmMo, String volumePath, - String secStorageUrl, String secStorageDir, String exportName, - String workerVmName) throws Exception { + String secStorageUrl, String secStorageDir, String exportName, + String workerVmName) throws Exception { String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl); String exportPath = secondaryMountPoint + "/" + secStorageDir + "/" + exportName; - + synchronized(exportPath.intern()) { if(!new File(exportPath).exists()) { Script command = new Script(false, "mkdir", _timeout, s_logger); command.add("-p"); command.add(exportPath); - if(command.execute() != null) + if(command.execute() != null) { throw new Exception("unable to prepare snapshot backup directory"); + } } } @@ -984,7 +987,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { // 4 MB is the minimum requirement for VM memory in VMware vmMo.cloneFromCurrentSnapshot(workerVmName, 0, 4, volumeDeviceInfo.second(), - VmwareHelper.getDiskDeviceDatastore(volumeDeviceInfo.first())); + VmwareHelper.getDiskDeviceDatastore(volumeDeviceInfo.first())); clonedVm = vmMo.getRunningHost().findVmOnHyperHost(workerVmName); if(clonedVm == null) { String msg = "Unable to create dummy VM to export volume. volume path: " + volumePath; @@ -1007,33 +1010,35 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { String snapshotMountRoot = secondaryMountPoint + "/" + getSnapshotRelativeDirInSecStorage(accountId, volumeId); File file = new File(snapshotMountRoot + "/" + backupUuid + ".ovf"); if(file.exists()) { - File snapshotdir = new File(snapshotMountRoot); - File[] ssfiles = snapshotdir.listFiles(); + File snapshotdir = new File(snapshotMountRoot); + File[] ssfiles = snapshotdir.listFiles(); // List filenames = new ArrayList(); - for (int i = 0; i < ssfiles.length; i++) { + for (int i = 0; i < ssfiles.length; i++) { String vmdkfile = ssfiles[i].getName(); if(vmdkfile.toLowerCase().startsWith(backupUuid) && vmdkfile.toLowerCase().endsWith(".vmdk")) { - // filenames.add(vmdkfile); - new File(vmdkfile).delete(); + // filenames.add(vmdkfile); + new File(vmdkfile).delete(); } - } - if(file.delete()) - return null; - } else { - File file1 = new File(snapshotMountRoot + "/" + backupUuid + ".ova"); - if(file1.exists()) { - if(file1.delete()) - return null; - } else { - return "Backup file does not exist. backupUuid: " + backupUuid; - } - } - return "Failed to delete snapshot backup file, backupUuid: " + backupUuid; - } + } + if(file.delete()) { + return null; + } + } else { + File file1 = new File(snapshotMountRoot + "/" + backupUuid + ".ova"); + if(file1.exists()) { + if(file1.delete()) { + return null; + } + } else { + return "Backup file does not exist. backupUuid: " + backupUuid; + } + } + return "Failed to delete snapshot backup file, backupUuid: " + backupUuid; + } private Pair copyVolumeToSecStorage(VmwareHostService hostService, VmwareHypervisorHost hyperHost, CopyVolumeCommand cmd, - String vmName, long volumeId, String poolId, String volumePath, - String secStorageUrl, String workerVmName) throws Exception { + String vmName, long volumeId, String poolId, String volumePath, + String secStorageUrl, String workerVmName) throws Exception { String volumeFolder = String.valueOf(volumeId) + "/"; VirtualMachineMO workerVm=null; @@ -1090,7 +1095,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { vmMo.createSnapshot(exportName, "Temporary snapshot for copy-volume command", false, false); exportVolumeToSecondaryStroage(vmMo, volumePath, secStorageUrl, "volumes/" + volumeFolder, exportName, - hostService.getWorkerName(hyperHost.getContext(), cmd, 1)); + hostService.getWorkerName(hyperHost.getContext(), cmd, 1)); return new Pair(volumeFolder, exportName); } finally { @@ -1110,7 +1115,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { } private Pair copyVolumeFromSecStorage(VmwareHypervisorHost hyperHost, long volumeId, - DatastoreMO dsMo, String secStorageUrl, String exportName) throws Exception { + DatastoreMO dsMo, String secStorageUrl, String exportName) throws Exception { String volumeFolder = String.valueOf(volumeId) + "/"; String newVolume = UUID.randomUUID().toString().replaceAll("-", ""); @@ -1119,91 +1124,91 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { return new Pair(volumeFolder, newVolume); } - //Fang: here I use a method to return the ovf and vmdk file names; Another way to do it: + // here we use a method to return the ovf and vmdk file names; Another way to do it: // create a new class, and like TemplateLocation.java and create templateOvfInfo.java to handle it; - private String getOVAFromMetafile(String metafileName) throws Exception { + private String getOVAFromMetafile(String metafileName) throws Exception { File ova_metafile = new File(metafileName); Properties props = null; FileInputStream strm = null; String ovaFileName = ""; - s_logger.info("Fang: getOVAfromMetaFile: metafileName " + metafileName); - try { - strm = new FileInputStream(ova_metafile); - if (null == strm) { - String msg = "Cannot read ova meat file. Error"; - s_logger.error(msg); - throw new Exception(msg); + s_logger.info("getOVAfromMetaFile: " + metafileName); + try { + strm = new FileInputStream(ova_metafile); + if (null == strm) { + String msg = "Cannot read ova meta file."; + s_logger.error(msg); + throw new Exception(msg); + } + + s_logger.info("loading properties from ova meta file: " + metafileName); + if (null != ova_metafile) { + props = new Properties(); + props.load(strm); + if (props == null) { + s_logger.info("getOVAfromMetaFile: props is null. "); + } + } + if (null != props) { + ovaFileName = props.getProperty("ova.filename"); + s_logger.info("ovafilename: " + ovaFileName); + String ovfFileName = props.getProperty("ovf"); + s_logger.info("ovffilename: " + ovfFileName); + int diskNum = Integer.parseInt(props.getProperty("numDisks")); + if (diskNum <= 0) { + String msg = "VMDK disk file number is 0. Error"; + s_logger.error(msg); + throw new Exception(msg); + } + String[] disks = new String[diskNum]; + for (int i = 0; i < diskNum; i++) { + // String diskNameKey = "disk" + Integer.toString(i+1) + ".name"; // Fang use this + String diskNameKey = "disk1.name"; + disks[i] = props.getProperty(diskNameKey); + s_logger.info("diskname " + disks[i]); + } + String exportDir = ova_metafile.getParent(); + s_logger.info("exportDir: " + exportDir); + // Important! we need to sync file system before we can safely use tar to work around a linux kernal bug(or feature) + s_logger.info("Sync file system before we package OVA..., before tar "); + s_logger.info("ova: " + ovaFileName + ", ovf:" + ovfFileName + ", vmdk:" + disks[0] + "."); + Script commandSync = new Script(true, "sync", 0, s_logger); + commandSync.execute(); + Script command = new Script(false, "tar", 0, s_logger); + command.setWorkDir(exportDir); // Fang: pass this in to the method? + command.add("-cf", ovaFileName); + command.add(ovfFileName); // OVF file should be the first file in OVA archive + for (String diskName : disks) { + command.add(diskName); + } + command.execute(); + s_logger.info("Package OVA for template in dir: " + exportDir + "cmd: " + command.toString()); + // to be safe, physically test existence of the target OVA file + if ((new File(exportDir + ovaFileName)).exists()) { + s_logger.info("ova file is created and ready to extract "); + return (ovaFileName); + } else { + String msg = exportDir + File.separator + ovaFileName + ".ova is not created as expected"; + s_logger.error(msg); + throw new Exception(msg); + } + } else { + String msg = "Error reading the ova meta file: " + metafileName; + s_logger.error(msg); + throw new Exception(msg); + } + } catch (Exception e) { + return null; + // Do something, re-throw the exception + } finally { + if (strm != null) { + try { + strm.close(); + } catch (Exception e) { + } + } } - s_logger.info("Fang: getOVAfromMetaFile: load strm " ); - if (null != ova_metafile) { - props = new Properties(); - props.load(strm); - if (props == null) { - s_logger.info("Fang: getOVAfromMetaFile: props is null. " ); - } - } - if (null != props) { - ovaFileName = props.getProperty("ova.filename"); - s_logger.info("Fang: ovafilename" + ovaFileName); - String ovfFileName = props.getProperty("ovf"); - s_logger.info("Fang: ovffilename" + ovfFileName); - int diskNum = Integer.parseInt(props.getProperty("numDisks")); - if (diskNum <= 0) { - String msg = "VMDK disk file number is 0. Error"; - s_logger.error(msg); - throw new Exception(msg); - } - String[] disks = new String[diskNum]; - for (int i = 0; i < diskNum; i++) { - //String diskNameKey = "disk" + Integer.toString(i+1) + ".name"; // Fang use this - String diskNameKey = "disk1.name"; - disks[i] = props.getProperty(diskNameKey); - s_logger.info("Fang: diskname " + disks[i]); - } - String exportDir = ova_metafile.getParent(); - s_logger.info("Fang: exportDir: " + exportDir); - // Important! we need to sync file system before we can safely use tar to work around a linux kernal bug(or feature) - s_logger.info("Fang: Sync file system before we package OVA..., before tar "); - s_logger.info("Fang: ova: " + ovaFileName+ ", ovf:" + ovfFileName + ", vmdk:" + disks[0] + "."); - Script commandSync = new Script(true, "sync", 0, s_logger); - commandSync.execute(); - Script command = new Script(false, "tar", 0, s_logger); - command.setWorkDir(exportDir); //Fang: pass this in to the method? - command.add("-cf", ovaFileName); - command.add(ovfFileName); // OVF file should be the first file in OVA archive - for(String diskName: disks) { - command.add(diskName); - } - command.execute(); - s_logger.info("Fang: Package OVA for template in dir: " + exportDir + "cmd: " + command.toString()); - // to be safe, physically test existence of the target OVA file - if((new File(exportDir + ovaFileName)).exists()) { - s_logger.info("Fang: ova file is created and ready to extract "); - return (ovaFileName); - } else { - String msg = exportDir + File.separator + ovaFileName + ".ova is not created as expected"; - s_logger.error(msg); - throw new Exception(msg); - } - } else { - String msg = "Error reading the ova meta file: " + metafileName; - s_logger.error(msg); - throw new Exception(msg); - } - } catch (Exception e) { - return null; - //Do something, re-throw the exception - } finally { - if (strm != null) { - try { - strm.close(); - } catch (Exception e) { - } - } - } - - } + } private String getOVFFilePath(String srcOVAFileName) { File file = new File(srcOVAFileName); @@ -1228,9 +1233,9 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { return "snapshots/" + accountId + "/" + volumeId; } - private long getVMSnapshotChainSize(VmwareContext context, VmwareHypervisorHost hyperHost, - String fileName, String poolUuid, String exceptFileName) - throws Exception{ + private long getVMSnapshotChainSize(VmwareContext context, VmwareHypervisorHost hyperHost, + String fileName, String poolUuid, String exceptFileName) + throws Exception{ long size = 0; ManagedObjectReference morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, poolUuid); DatastoreMO dsMo = new DatastoreMO(context, morDs); @@ -1250,10 +1255,11 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { if (result != null) { List info = result.getFile(); for (FileInfo fi : info) { - if(exceptFileName != null && fi.getPath().contains(exceptFileName)) + if(exceptFileName != null && fi.getPath().contains(exceptFileName)) { continue; - else + } else { size = size + fi.getFileSize(); + } } } } @@ -1261,24 +1267,30 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { } private String extractSnapshotBaseFileName(String input) { - if(input == null) + if(input == null) { return null; + } String result = input; if (result.endsWith(".vmdk")){ // get rid of vmdk file extension result = result.substring(0, result.length() - (".vmdk").length()); } if(result.contains("/")) + { result = result.substring(result.indexOf ("/") + 1,result.length()); // remove VM name path - if(result.contains("ROOT") && result.split("-").length > 1) + } + if(result.contains("ROOT") && result.split("-").length > 1) { return "ROOT"; - if(result.split("-").length == 1) // e.g 4da6dcbd412c47b59f96c7ff6dbd7216.vmdk + } + if(result.split("-").length == 1) { return result; - if(result.split("-").length == 2) // e.g 4da6dcbd412c47b59f96c7ff6dbd7216-000001.vmdk + } + if(result.split("-").length == 2) { return result.split("-")[0]; - else + } else { return result; + } } - + @Override public CreateVMSnapshotAnswer execute(VmwareHostService hostService, CreateVMSnapshotCommand cmd) { List volumeTOs = cmd.getVolumeTOs(); @@ -1304,8 +1316,9 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { } vmMo = hyperHost.findVmOnHyperHost(vmName); - if(vmMo == null) + if(vmMo == null) { vmMo = hyperHost.findVmOnPeerHyperHost(vmName); + } if (vmMo == null) { String msg = "Unable to find VM for CreateVMSnapshotCommand"; s_logger.debug(msg); @@ -1326,8 +1339,9 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { if (vmdkName.endsWith(".vmdk")){ vmdkName = vmdkName.substring(0, vmdkName.length() - (".vmdk").length()); } - if(vmdkName.contains("/")) - vmdkName = vmdkName.substring(vmdkName.indexOf ("/") + 1,vmdkName.length()); + if(vmdkName.contains("/")) { + vmdkName = vmdkName.substring(vmdkName.indexOf ("/") + 1,vmdkName.length()); + } String baseName = extractSnapshotBaseFileName(vmdkName); mapNewDisk.put(baseName, vmdkName); } @@ -1338,12 +1352,12 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { // get volume's chain size for this VM snapshot, exclude current volume vdisk long size = getVMSnapshotChainSize(context,hyperHost,baseName + "*.vmdk", volumeTO.getPoolUuid(), newPath); - + if(volumeTO.getType()== Volume.Type.ROOT){ // add memory snapshot size size = size + getVMSnapshotChainSize(context,hyperHost,cmd.getVmName()+"*.vmsn",volumeTO.getPoolUuid(),null); } - + volumeTO.setChainSize(size); volumeTO.setPath(newPath); } @@ -1362,7 +1376,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { } } - @Override + @Override public DeleteVMSnapshotAnswer execute(VmwareHostService hostService, DeleteVMSnapshotCommand cmd) { List listVolumeTo = cmd.getVolumeTOs(); VirtualMachineMO vmMo = null; @@ -1373,8 +1387,9 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { try { VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, cmd); vmMo = hyperHost.findVmOnHyperHost(vmName); - if(vmMo == null) + if(vmMo == null) { vmMo = hyperHost.findVmOnPeerHyperHost(vmName); + } if (vmMo == null) { String msg = "Unable to find VM for DeleteVMSnapshotCommand"; s_logger.debug(msg); @@ -1400,8 +1415,9 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { if (vmdkName.endsWith(".vmdk")) { vmdkName = vmdkName.substring(0, vmdkName.length() - (".vmdk").length()); } - if(vmdkName.contains("/")) + if(vmdkName.contains("/")) { vmdkName = vmdkName.substring(vmdkName.indexOf ("/") + 1,vmdkName.length()); + } String baseName = extractSnapshotBaseFileName(vmdkName); mapNewDisk.put(baseName, vmdkName); } @@ -1414,7 +1430,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { if(volumeTo.getType()== Volume.Type.ROOT){ // add memory snapshot size size = size + getVMSnapshotChainSize(context,hyperHost,cmd.getVmName()+"*.vmsn",volumeTo.getPoolUuid(),null); - } + } volumeTo.setChainSize(size); volumeTo.setPath(newPath); } @@ -1427,7 +1443,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { } } - @Override + @Override public RevertToVMSnapshotAnswer execute(VmwareHostService hostService, RevertToVMSnapshotCommand cmd) { String snapshotName = cmd.getTarget().getSnapshotName(); String vmName = cmd.getVmName(); @@ -1453,8 +1469,9 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { HostMO hostMo = (HostMO) hyperHost; vmMo = hyperHost.findVmOnHyperHost(vmName); - if(vmMo == null) + if(vmMo == null) { vmMo = hyperHost.findVmOnPeerHyperHost(vmName); + } if (vmMo == null) { String msg = "Unable to find VM for RevertToVMSnapshotCommand"; s_logger.debug(msg); @@ -1480,8 +1497,9 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { if (vmdkName.endsWith(".vmdk")) { vmdkName = vmdkName.substring(0, vmdkName.length() - (".vmdk").length()); } - if(vmdkName.contains("/")) - vmdkName = vmdkName.substring(vmdkName.indexOf ("/") + 1,vmdkName.length()); + if(vmdkName.contains("/")) { + vmdkName = vmdkName.substring(vmdkName.indexOf ("/") + 1,vmdkName.length()); + } String baseName = extractSnapshotBaseFileName(vmdkName); mapNewDisk.put(baseName, vmdkName); } diff --git a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java index 38b2a67ba46..138f725087b 100644 --- a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java +++ b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java @@ -27,7 +27,6 @@ import java.util.List; import java.util.Map; import java.util.UUID; -import com.cloud.utils.exception.ExceptionUtil; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; @@ -904,7 +903,7 @@ public class VmwareStorageProcessor implements StorageProcessor { long virtualSize = processor.getTemplateVirtualSize(installFullPath, templateUniqueName); postCreatePrivateTemplate(installFullPath, templateId, templateUniqueName, physicalSize, virtualSize); - writeMetaOvaForTemplate(installFullPath, backupSSUuid + File.separator + backupSSUuid + ".ovf", templateVMDKName, templateUniqueName, physicalSize); + writeMetaOvaForTemplate(installFullPath, backupSSUuid + ".ovf", templateVMDKName, templateUniqueName, physicalSize); return new Ternary(installPath + "/" + templateUniqueName + ".ova", physicalSize, virtualSize); } finally { // TODO, clean up left over files @@ -1509,9 +1508,9 @@ public class VmwareStorageProcessor implements StorageProcessor { + backupName.replace(".ova", ".ovf"); } else { srcOVAFileName = secondaryMountPoint + "/" + secStorageDir + "/" - + backupName + "." + ImageFormat.OVA.getFileExtension(); + + backupName + "." + ImageFormat.OVA.getFileExtension(); srcOVFFileName = secondaryMountPoint + "/" + secStorageDir + "/" - + backupName + ".ovf"; + + backupName + ".ovf"; } String snapshotDir = ""; if (backupName.contains("/")){