use of com.cloud.hypervisor.vmware.mo.VmwareHypervisorHost in project cloudstack by apache.
the class VmwareStorageProcessor method copyTemplateToPrimaryStorage.
@Override
public Answer copyTemplateToPrimaryStorage(CopyCommand cmd) {
DataTO srcData = cmd.getSrcTO();
TemplateObjectTO template = (TemplateObjectTO) srcData;
DataStoreTO srcStore = srcData.getDataStore();
if (!(srcStore instanceof NfsTO)) {
return new CopyCmdAnswer("unsupported protocol");
}
NfsTO nfsImageStore = (NfsTO) srcStore;
DataTO destData = cmd.getDestTO();
DataStoreTO destStore = destData.getDataStore();
DataStoreTO primaryStore = destStore;
String configurationId = ((TemplateObjectTO) destData).getDeployAsIsConfiguration();
String secondaryStorageUrl = nfsImageStore.getUrl();
assert secondaryStorageUrl != null;
boolean managed = false;
String storageHost = null;
int storagePort = Integer.MIN_VALUE;
String managedStoragePoolName = null;
String managedStoragePoolRootVolumeName = null;
String chapInitiatorUsername = null;
String chapInitiatorSecret = null;
String chapTargetUsername = null;
String chapTargetSecret = null;
if (destStore instanceof PrimaryDataStoreTO) {
PrimaryDataStoreTO destPrimaryDataStoreTo = (PrimaryDataStoreTO) destStore;
Map<String, String> details = destPrimaryDataStoreTo.getDetails();
if (details != null) {
managed = Boolean.parseBoolean(details.get(PrimaryDataStoreTO.MANAGED));
if (managed) {
storageHost = details.get(PrimaryDataStoreTO.STORAGE_HOST);
try {
storagePort = Integer.parseInt(details.get(PrimaryDataStoreTO.STORAGE_PORT));
} catch (Exception ex) {
storagePort = 3260;
}
managedStoragePoolName = details.get(PrimaryDataStoreTO.MANAGED_STORE_TARGET);
managedStoragePoolRootVolumeName = details.get(PrimaryDataStoreTO.MANAGED_STORE_TARGET_ROOT_VOLUME);
chapInitiatorUsername = details.get(PrimaryDataStoreTO.CHAP_INITIATOR_USERNAME);
chapInitiatorSecret = details.get(PrimaryDataStoreTO.CHAP_INITIATOR_SECRET);
chapTargetUsername = details.get(PrimaryDataStoreTO.CHAP_TARGET_USERNAME);
chapTargetSecret = details.get(PrimaryDataStoreTO.CHAP_TARGET_SECRET);
}
}
}
String templateUrl = secondaryStorageUrl + "/" + srcData.getPath();
Pair<String, String> templateInfo = VmwareStorageLayoutHelper.decodeTemplateRelativePathAndNameFromUrl(secondaryStorageUrl, templateUrl, template.getName());
VmwareContext context = hostService.getServiceContext(cmd);
if (context == null) {
return new CopyCmdAnswer("Failed to create a VMware context, check the management server logs or the SSVM log for details");
}
VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, cmd);
DatastoreMO dsMo = null;
try {
String storageUuid = managed ? managedStoragePoolName : primaryStore.getUuid();
// Generate a new template uuid if the template is marked as deploy-as-is,
// as it supports multiple configurations
String templateUuidName = template.isDeployAsIs() ? UUID.randomUUID().toString() : deriveTemplateUuidOnHost(hyperHost, storageUuid, templateInfo.second());
DatacenterMO dcMo = new DatacenterMO(context, hyperHost.getHyperHostDatacenter());
VirtualMachineMO templateMo = VmwareHelper.pickOneVmOnRunningHost(dcMo.findVmByNameAndLabel(templateUuidName), true);
Pair<VirtualMachineMO, Long> vmInfo = null;
final ManagedObjectReference morDs;
if (managed) {
morDs = prepareManagedDatastore(context, hyperHost, null, managedStoragePoolName, storageHost, storagePort, chapInitiatorUsername, chapInitiatorSecret, chapTargetUsername, chapTargetSecret);
} else {
morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, storageUuid);
}
assert (morDs != null);
dsMo = new DatastoreMO(context, morDs);
if (templateMo == null) {
if (s_logger.isInfoEnabled()) {
s_logger.info("Template " + templateInfo.second() + " is not setup yet. Set up template from secondary storage with uuid name: " + templateUuidName);
}
if (managed) {
vmInfo = copyTemplateFromSecondaryToPrimary(hyperHost, dsMo, secondaryStorageUrl, templateInfo.first(), templateInfo.second(), managedStoragePoolRootVolumeName, false, _nfsVersion, configurationId);
VirtualMachineMO vmMo = vmInfo.first();
vmMo.unregisterVm();
String[] vmwareLayoutFilePair = VmwareStorageLayoutHelper.getVmdkFilePairManagedDatastorePath(dsMo, managedStoragePoolRootVolumeName, managedStoragePoolRootVolumeName, VmwareStorageLayoutType.VMWARE, false);
String[] legacyCloudStackLayoutFilePair = VmwareStorageLayoutHelper.getVmdkFilePairManagedDatastorePath(dsMo, null, managedStoragePoolRootVolumeName, VmwareStorageLayoutType.CLOUDSTACK_LEGACY, false);
dsMo.moveDatastoreFile(vmwareLayoutFilePair[0], dcMo.getMor(), dsMo.getMor(), legacyCloudStackLayoutFilePair[0], dcMo.getMor(), true);
for (int i = 1; i < vmwareLayoutFilePair.length; i++) {
dsMo.moveDatastoreFile(vmwareLayoutFilePair[i], dcMo.getMor(), dsMo.getMor(), legacyCloudStackLayoutFilePair[i], dcMo.getMor(), true);
}
String folderToDelete = dsMo.getDatastorePath(managedStoragePoolRootVolumeName, true);
dsMo.deleteFolder(folderToDelete, dcMo.getMor());
} else {
vmInfo = copyTemplateFromSecondaryToPrimary(hyperHost, dsMo, secondaryStorageUrl, templateInfo.first(), templateInfo.second(), templateUuidName, true, _nfsVersion, configurationId);
}
} else {
s_logger.info("Template " + templateInfo.second() + " has already been setup, skip the template setup process in primary storage");
}
TemplateObjectTO newTemplate = new TemplateObjectTO();
if (managed) {
if (dsMo != null) {
String path = dsMo.getDatastorePath(managedStoragePoolRootVolumeName + ".vmdk");
newTemplate.setPath(path);
}
} else {
if (dsMo.getDatastoreType().equalsIgnoreCase("VVOL")) {
newTemplate.setPath(CustomFieldConstants.CLOUD_UUID + "-" + templateUuidName);
} else {
newTemplate.setPath(templateUuidName);
}
}
newTemplate.setDeployAsIsConfiguration(configurationId);
newTemplate.setSize((vmInfo != null) ? vmInfo.second() : new Long(0));
return new CopyCmdAnswer(newTemplate);
} catch (Throwable e) {
return new CopyCmdAnswer(hostService.createLogMessageException(e, cmd));
} finally {
if (dsMo != null && managedStoragePoolName != null) {
try {
removeVmfsDatastore(cmd, hyperHost, VmwareResource.getDatastoreName(managedStoragePoolName), storageHost, storagePort, trimIqn(managedStoragePoolName));
} catch (Exception ex) {
s_logger.error("Unable to remove the following datastore: " + VmwareResource.getDatastoreName(managedStoragePoolName), ex);
}
}
}
}
use of com.cloud.hypervisor.vmware.mo.VmwareHypervisorHost in project cloudstack by apache.
the class VmwareStorageProcessor method createTemplateFromVolume.
@Override
public Answer createTemplateFromVolume(CopyCommand cmd) {
VolumeObjectTO volume = (VolumeObjectTO) cmd.getSrcTO();
TemplateObjectTO template = (TemplateObjectTO) cmd.getDestTO();
DataStoreTO imageStore = template.getDataStore();
if (!(imageStore instanceof NfsTO)) {
return new CopyCmdAnswer("unsupported protocol");
}
NfsTO nfsImageStore = (NfsTO) imageStore;
String secondaryStoragePoolURL = nfsImageStore.getUrl();
String volumePath = volume.getPath();
String details = null;
VirtualMachineMO vmMo = null;
VirtualMachineMO workerVmMo = null;
VmwareContext context = hostService.getServiceContext(cmd);
try {
VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, cmd);
if (volume.getVmName() == null) {
ManagedObjectReference secMorDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, volume.getDataStore().getUuid());
DatastoreMO dsMo = new DatastoreMO(hyperHost.getContext(), secMorDs);
workerVmMo = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, "workervm" + volume.getUuid(), null);
if (workerVmMo == null) {
throw new Exception("Unable to find created worker VM");
}
vmMo = workerVmMo;
String vmdkDataStorePath = VmwareStorageLayoutHelper.getLegacyDatastorePathFromVmdkFileName(dsMo, volumePath + ".vmdk");
vmMo.attachDisk(new String[] { vmdkDataStorePath }, secMorDs);
} else {
vmMo = hyperHost.findVmOnHyperHost(volume.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(volume.getVmName());
if (vmMo == null) {
// This means either the volume is on a zone wide storage pool or VM is deleted by external entity.
// Look for the VM in the datacenter.
ManagedObjectReference dcMor = hyperHost.getHyperHostDatacenter();
DatacenterMO dcMo = new DatacenterMO(context, dcMor);
vmMo = dcMo.findVm(volume.getVmName());
}
if (vmMo == null) {
String msg = "Unable to find the owner VM for volume operation. vm: " + volume.getVmName();
s_logger.error(msg);
throw new Exception(msg);
}
}
}
Ternary<String, Long, Long> result = createTemplateFromVolume(context, vmMo, hyperHost, template.getPath(), template.getId(), template.getName(), secondaryStoragePoolURL, volumePath, hostService.getWorkerName(context, cmd, 0, null), _nfsVersion);
TemplateObjectTO newTemplate = new TemplateObjectTO();
newTemplate.setPath(result.first());
newTemplate.setFormat(ImageFormat.OVA);
newTemplate.setSize(result.third());
newTemplate.setPhysicalSize(result.second());
return new CopyCmdAnswer(newTemplate);
} catch (Throwable e) {
return new CopyCmdAnswer(hostService.createLogMessageException(e, cmd));
} finally {
try {
if (volume.getVmName() == null && workerVmMo != null) {
workerVmMo.detachAllDisksAndDestroy();
}
} catch (Throwable e) {
s_logger.error("Failed to destroy worker VM created for detached volume");
}
}
}
use of com.cloud.hypervisor.vmware.mo.VmwareHypervisorHost in project cloudstack by apache.
the class VmwareStorageProcessor method createVolumeFromSnapshot.
@Override
public Answer createVolumeFromSnapshot(CopyCommand cmd) {
DataTO srcData = cmd.getSrcTO();
SnapshotObjectTO snapshot = (SnapshotObjectTO) srcData;
DataTO destData = cmd.getDestTO();
DataStoreTO pool = destData.getDataStore();
DataStoreTO imageStore = srcData.getDataStore();
if (!(imageStore instanceof NfsTO)) {
return new CopyCmdAnswer("unsupported protocol");
}
NfsTO nfsImageStore = (NfsTO) imageStore;
String primaryStorageNameLabel = pool.getUuid();
String secondaryStorageUrl = nfsImageStore.getUrl();
String backedUpSnapshotUuid = snapshot.getPath();
int index = backedUpSnapshotUuid.lastIndexOf(File.separator);
String backupPath = backedUpSnapshotUuid.substring(0, index);
backedUpSnapshotUuid = backedUpSnapshotUuid.substring(index + 1);
String details;
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);
String newVolumeName = VmwareHelper.getVCenterSafeUuid(primaryDsMo);
// strip off the extension since restoreVolumeFromSecStorage internally will append suffix there.
if (backedUpSnapshotUuid.endsWith(".ova")) {
backedUpSnapshotUuid = backedUpSnapshotUuid.replace(".ova", "");
} else if (backedUpSnapshotUuid.endsWith(".ovf")) {
backedUpSnapshotUuid = backedUpSnapshotUuid.replace(".ovf", "");
}
restoreVolumeFromSecStorage(hyperHost, primaryDsMo, newVolumeName, secondaryStorageUrl, backupPath, backedUpSnapshotUuid, (long) cmd.getWait() * 1000, _nfsVersion);
VolumeObjectTO newVol = new VolumeObjectTO();
newVol.setPath(newVolumeName);
return new CopyCmdAnswer(newVol);
} catch (Throwable e) {
hostService.createLogMessageException(e, cmd);
details = String.format("Failed to create volume from snapshot due to exception: [%s]", VmwareHelper.getExceptionMessage(e));
}
return new CopyCmdAnswer(details);
}
use of com.cloud.hypervisor.vmware.mo.VmwareHypervisorHost in project cloudstack by apache.
the class VmwareStorageProcessor method checkDataStoreStoragePolicyCompliance.
@Override
public Answer checkDataStoreStoragePolicyCompliance(CheckDataStoreStoragePolicyComplainceCommand cmd) {
String primaryStorageNameLabel = cmd.getStoragePool().getUuid();
String storagePolicyId = cmd.getStoragePolicyId();
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);
boolean isDatastoreStoragePolicyComplaint = primaryDsMo.isDatastoreStoragePolicyComplaint(storagePolicyId);
String failedMessage = String.format("DataStore %s is not complaince with storage policy id %s", primaryStorageNameLabel, storagePolicyId);
if (!isDatastoreStoragePolicyComplaint)
return new Answer(cmd, isDatastoreStoragePolicyComplaint, failedMessage);
else
return new Answer(cmd, isDatastoreStoragePolicyComplaint, null);
} catch (Throwable e) {
hostService.createLogMessageException(e, cmd);
String details = String.format("Exception while checking if datastore [%s] is storage policy [%s] complaince due to: [%s]", primaryStorageNameLabel, storagePolicyId, VmwareHelper.getExceptionMessage(e));
return new Answer(cmd, false, details);
}
}
use of com.cloud.hypervisor.vmware.mo.VmwareHypervisorHost in project cloudstack by apache.
the class VmwareResource method migrateVolume.
private Answer migrateVolume(MigrateVolumeCommand cmd) {
Answer answer = null;
String path = cmd.getVolumePath();
VmwareHypervisorHost hyperHost = getHyperHost(getServiceContext());
VirtualMachineMO vmMo = null;
DatastoreMO sourceDsMo = null;
DatastoreMO destinationDsMo = null;
ManagedObjectReference morSourceDS = null;
ManagedObjectReference morDestinationDS = null;
String vmdkDataStorePath = null;
boolean isvVolsInvolved = false;
String vmName = null;
try {
// OfflineVmwareMigration: we need to refactor the worker vm creation out for use in migration methods as well as here
// OfflineVmwareMigration: this method is 100 lines and needs refactorring anyway
// we need to spawn a worker VM to attach the volume to and move it
morSourceDS = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, cmd.getSourcePool().getUuid());
sourceDsMo = new DatastoreMO(hyperHost.getContext(), morSourceDS);
VmwareHypervisorHost hyperHostInTargetCluster = VmwareHelper.getHostMOFromHostName(getServiceContext(), cmd.getHostGuidInTargetCluster());
VmwareHypervisorHost dsHost = hyperHostInTargetCluster == null ? hyperHost : hyperHostInTargetCluster;
String targetDsName = cmd.getTargetPool().getUuid();
morDestinationDS = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(dsHost, targetDsName);
if (morDestinationDS == null) {
String msg = "Unable to find the target datastore: " + targetDsName + " on host: " + dsHost.getHyperHostName();
s_logger.error(msg);
throw new CloudRuntimeException(msg);
}
destinationDsMo = new DatastoreMO(hyperHost.getContext(), morDestinationDS);
vmName = getWorkerName(getServiceContext(), cmd, 0, sourceDsMo);
if (destinationDsMo.getDatastoreType().equalsIgnoreCase("VVOL")) {
isvVolsInvolved = true;
vmName = getWorkerName(getServiceContext(), cmd, 0, destinationDsMo);
}
// OfflineVmwareMigration: refactor for re-use
// OfflineVmwareMigration: 1. find data(store)
// OfflineVmwareMigration: more robust would be to find the store given the volume as it might have been moved out of band or due to error
// example: DatastoreMO existingVmDsMo = new DatastoreMO(dcMo.getContext(), dcMo.findDatastore(fileInDatastore.getDatastoreName()));
s_logger.info("Create worker VM " + vmName);
// OfflineVmwareMigration: 2. create the worker with access to the data(store)
vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, sourceDsMo, vmName, HypervisorHostHelper.getMinimumHostHardwareVersion(hyperHost, hyperHostInTargetCluster));
if (vmMo == null) {
// OfflineVmwareMigration: don't throw a general Exception but think of a specific one
throw new CloudRuntimeException("Unable to create a worker VM for volume operation");
}
synchronized (this) {
// OfflineVmwareMigration: 3. attach the disk to the worker
String vmdkFileName = path + VMDK_EXTENSION;
vmdkDataStorePath = VmwareStorageLayoutHelper.getLegacyDatastorePathFromVmdkFileName(sourceDsMo, vmdkFileName);
if (!sourceDsMo.fileExists(vmdkDataStorePath)) {
if (s_logger.isDebugEnabled()) {
s_logger.debug(String.format("path not found (%s), trying under '%s'", vmdkFileName, path));
}
vmdkDataStorePath = VmwareStorageLayoutHelper.getVmwareDatastorePathFromVmdkFileName(sourceDsMo, path, vmdkFileName);
}
if (!sourceDsMo.folderExists(String.format("[%s]", sourceDsMo.getName()), path) || !sourceDsMo.fileExists(vmdkDataStorePath)) {
if (s_logger.isDebugEnabled()) {
s_logger.debug(String.format("path not found (%s), trying under '%s'", vmdkFileName, vmName));
}
vmdkDataStorePath = VmwareStorageLayoutHelper.getVmwareDatastorePathFromVmdkFileName(sourceDsMo, vmName, vmdkFileName);
}
if (!sourceDsMo.folderExists(String.format("[%s]", sourceDsMo.getName()), vmName) || !sourceDsMo.fileExists(vmdkDataStorePath)) {
vmdkDataStorePath = sourceDsMo.searchFileInSubFolders(vmdkFileName, true, null);
}
if (s_logger.isDebugEnabled()) {
s_logger.debug(String.format("attaching %s to %s for migration", vmdkDataStorePath, vmMo.getVmName()));
}
vmMo.attachDisk(new String[] { vmdkDataStorePath }, morSourceDS);
}
// OfflineVmwareMigration: 4. find the (worker-) VM
// find VM through datacenter (VM is not at the target host yet)
vmMo = hyperHost.findVmOnPeerHyperHost(vmName);
if (vmMo == null) {
String msg = "VM " + vmName + " does not exist in VMware datacenter";
s_logger.error(msg);
throw new Exception(msg);
}
if (s_logger.isTraceEnabled()) {
VirtualDisk[] disks = vmMo.getAllDiskDevice();
String format = "disk %d is attached as %s";
for (VirtualDisk disk : disks) {
s_logger.trace(String.format(format, disk.getKey(), vmMo.getVmdkFileBaseName(disk)));
}
}
// OfflineVmwareMigration: 5. create a relocate spec and perform
Pair<VirtualDisk, String> vdisk = vmMo.getDiskDevice(path);
if (vdisk == null) {
if (s_logger.isTraceEnabled())
s_logger.trace("migrate volume done (failed)");
throw new CloudRuntimeException("No such disk device: " + path);
}
VirtualDisk disk = vdisk.first();
String vmdkAbsFile = getAbsoluteVmdkFile(disk);
if (vmdkAbsFile != null && !vmdkAbsFile.isEmpty()) {
vmMo.updateAdapterTypeIfRequired(vmdkAbsFile);
}
// OfflineVmwareMigration: this may have to be disected and executed in separate steps
answer = migrateAndAnswer(vmMo, cmd.getTargetPool().getUuid(), hyperHost, cmd);
} catch (Exception e) {
String msg = String.format("Migration of volume '%s' failed due to %s", cmd.getVolumePath(), e.getLocalizedMessage());
s_logger.error(msg, e);
answer = new Answer(cmd, false, msg);
} finally {
try {
// OfflineVmwareMigration: worker *may* have been renamed
vmName = vmMo.getVmName();
s_logger.info("Dettaching disks before destroying worker VM '" + vmName + "' after volume migration");
VirtualDisk[] disks = vmMo.getAllDiskDevice();
String format = "disk %d was migrated to %s";
for (VirtualDisk disk : disks) {
if (s_logger.isTraceEnabled()) {
s_logger.trace(String.format(format, disk.getKey(), vmMo.getVmdkFileBaseName(disk)));
}
vmdkDataStorePath = VmwareStorageLayoutHelper.getLegacyDatastorePathFromVmdkFileName(destinationDsMo, vmMo.getVmdkFileBaseName(disk) + VMDK_EXTENSION);
vmMo.detachDisk(vmdkDataStorePath, false);
}
s_logger.info("Destroy worker VM '" + vmName + "' after volume migration");
vmMo.destroy();
} catch (Throwable e) {
s_logger.info("Failed to destroy worker VM: " + vmName);
}
}
if (answer instanceof MigrateVolumeAnswer) {
if (!isvVolsInvolved) {
String newPath = ((MigrateVolumeAnswer) answer).getVolumePath();
String vmdkFileName = newPath + VMDK_EXTENSION;
try {
VmwareStorageLayoutHelper.syncVolumeToRootFolder(destinationDsMo.getOwnerDatacenter().first(), destinationDsMo, newPath, vmName);
vmdkDataStorePath = VmwareStorageLayoutHelper.getLegacyDatastorePathFromVmdkFileName(destinationDsMo, vmdkFileName);
if (!destinationDsMo.fileExists(vmdkDataStorePath)) {
String msg = String.format("Migration of volume '%s' failed; file (%s) not found as path '%s'", cmd.getVolumePath(), vmdkFileName, vmdkDataStorePath);
s_logger.error(msg);
answer = new Answer(cmd, false, msg);
}
} catch (Exception e) {
String msg = String.format("Migration of volume '%s' failed due to %s", cmd.getVolumePath(), e.getLocalizedMessage());
s_logger.error(msg, e);
answer = new Answer(cmd, false, msg);
}
}
}
return answer;
}
Aggregations