mirror of https://github.com/apache/cloudstack.git
CLOUDSTACK-6170 (VMware root-disk support for managed storage)
This commit is contained in:
parent
412af7c2e6
commit
fe0c9768cf
|
|
@ -27,6 +27,7 @@ import com.cloud.storage.Storage.StoragePoolType;
|
|||
public class PrimaryDataStoreTO implements DataStoreTO {
|
||||
public static final String MANAGED = PrimaryDataStore.MANAGED;
|
||||
public static final String STORAGE_HOST = PrimaryDataStore.STORAGE_HOST;
|
||||
public static final String STORAGE_PORT = PrimaryDataStore.STORAGE_PORT;
|
||||
public static final String MANAGED_STORE_TARGET = PrimaryDataStore.MANAGED_STORE_TARGET;
|
||||
public static final String MANAGED_STORE_TARGET_ROOT_VOLUME = PrimaryDataStore.MANAGED_STORE_TARGET_ROOT_VOLUME;
|
||||
public static final String CHAP_INITIATOR_USERNAME = PrimaryDataStore.CHAP_INITIATOR_USERNAME;
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import com.cloud.storage.StoragePool;
|
|||
public interface PrimaryDataStoreInfo extends StoragePool {
|
||||
static final String MANAGED = "managed";
|
||||
static final String STORAGE_HOST= "storageHost";
|
||||
static final String STORAGE_PORT = "storagePort";
|
||||
static final String MANAGED_STORE_TARGET = "managedStoreTarget";
|
||||
static final String MANAGED_STORE_TARGET_ROOT_VOLUME = "managedStoreTargetRootVolume";
|
||||
static final String CHAP_INITIATOR_USERNAME = "chapInitiatorUsername";
|
||||
|
|
|
|||
|
|
@ -527,7 +527,10 @@ public class VolumeServiceImpl implements VolumeService {
|
|||
TemplateObjectTO templateObjectTo = (TemplateObjectTO)answer.getNewData();
|
||||
|
||||
volume.setPath(templateObjectTo.getPath());
|
||||
volume.setFormat(templateObjectTo.getFormat());
|
||||
|
||||
if (templateObjectTo.getFormat() != null) {
|
||||
volume.setFormat(templateObjectTo.getFormat());
|
||||
}
|
||||
|
||||
volDao.update(volume.getId(), volume);
|
||||
}
|
||||
|
|
@ -682,6 +685,7 @@ public class VolumeServiceImpl implements VolumeService {
|
|||
|
||||
details.put(PrimaryDataStore.MANAGED, Boolean.TRUE.toString());
|
||||
details.put(PrimaryDataStore.STORAGE_HOST, destPrimaryDataStore.getHostAddress());
|
||||
details.put(PrimaryDataStore.STORAGE_PORT, String.valueOf(destPrimaryDataStore.getPort()));
|
||||
// for managed storage, the storage repository (XenServer) or datastore (ESX) name is based off of the iScsiName property of a volume
|
||||
details.put(PrimaryDataStore.MANAGED_STORE_TARGET, volumeInfo.get_iScsiName());
|
||||
details.put(PrimaryDataStore.MANAGED_STORE_TARGET_ROOT_VOLUME, volumeInfo.getName());
|
||||
|
|
|
|||
|
|
@ -33,9 +33,14 @@ public interface VmwareHostService {
|
|||
|
||||
String getWorkerName(VmwareContext context, Command cmd, int workerSequence);
|
||||
|
||||
ManagedObjectReference prepareManagedDatastore(VmwareHypervisorHost hyperHost, String iScsiName,
|
||||
String storageHost, int storagePort, String chapInitiatorUsername, String chapInitiatorSecret,
|
||||
String chapTargetUsername, String chapTargetSecret) throws Exception;
|
||||
|
||||
ManagedObjectReference prepareManagedStorage(VmwareHypervisorHost hyperHost, String iScsiName,
|
||||
String storageHost, int storagePort, String chapInitiatorUsername, String chapInitiatorSecret,
|
||||
String chapTargetUsername, String chapTargetSecret, long size, Command cmd) throws Exception;
|
||||
|
||||
void handleDatastoreAndVmdkDetach(String iqn, String storageHost, int storagePort) throws Exception;
|
||||
|
||||
void removeManagedTargetsFromCluster(List<String> managedIqns) throws Exception;
|
||||
|
|
|
|||
|
|
@ -1824,13 +1824,20 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
|||
vmMo.ensureScsiDeviceController();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ManagedObjectReference prepareManagedDatastore(VmwareHypervisorHost hyperHost, String iScsiName,
|
||||
String storageHost, int storagePort, String chapInitiatorUsername, String chapInitiatorSecret,
|
||||
String chapTargetUsername, String chapTargetSecret) throws Exception {
|
||||
return getVmfsDatastore(hyperHost, VmwareResource.getDatastoreName(iScsiName), storageHost, storagePort,
|
||||
VmwareResource.trimIqn(iScsiName), chapInitiatorUsername, chapInitiatorSecret, chapTargetUsername, chapTargetSecret);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ManagedObjectReference prepareManagedStorage(VmwareHypervisorHost hyperHost, String iScsiName,
|
||||
String storageHost, int storagePort, String chapInitiatorUsername, String chapInitiatorSecret,
|
||||
String chapTargetUsername, String chapTargetSecret, long size, Command cmd) throws Exception {
|
||||
ManagedObjectReference morDs = getVmfsDatastore(hyperHost, VmwareResource.getDatastoreName(iScsiName),
|
||||
storageHost, storagePort, VmwareResource.trimIqn(iScsiName), chapInitiatorUsername, chapInitiatorSecret,
|
||||
chapTargetUsername, chapTargetSecret);
|
||||
ManagedObjectReference morDs = prepareManagedDatastore(hyperHost, iScsiName, storageHost, storagePort,
|
||||
chapInitiatorUsername, chapInitiatorSecret, chapTargetUsername, chapTargetSecret);
|
||||
|
||||
DatastoreMO dsMo = new DatastoreMO(getServiceContext(null), morDs);
|
||||
|
||||
|
|
@ -1908,7 +1915,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
|||
|
||||
if (isManaged) {
|
||||
if (volumeTO.getVolumeType() == Volume.Type.ROOT) {
|
||||
datastoreDiskPath = VmwareStorageLayoutHelper.syncVolumeToVmDefaultFolder(dcMo, vmMo.getName(), dsMo, dsMo.getName());
|
||||
datastoreDiskPath = VmwareStorageLayoutHelper.syncVolumeToVmDefaultFolder(dcMo, vmMo.getName(), dsMo, volumeTO.getName());
|
||||
}
|
||||
else {
|
||||
datastoreDiskPath = dsMo.getDatastorePath(dsMo.getName() + ".vmdk");
|
||||
|
|
|
|||
|
|
@ -314,6 +314,13 @@ public class VmwareSecondaryStorageResourceHandler implements SecondaryStorageRe
|
|||
return _resource.getRootDir(storageUrl);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ManagedObjectReference prepareManagedDatastore(VmwareHypervisorHost hyperHost, String iScsiName,
|
||||
String storageHost, int storagePort, String chapInitiatorUsername, String chapInitiatorSecret,
|
||||
String chapTargetUsername, String chapTargetSecret) throws Exception {
|
||||
throw new OperationNotSupportedException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ManagedObjectReference prepareManagedStorage(VmwareHypervisorHost hyperHost, String iScsiName,
|
||||
String storageHost, int storagePort, String chapInitiatorUsername, String chapInitiatorSecret,
|
||||
|
|
|
|||
|
|
@ -188,44 +188,121 @@ public class VmwareStorageProcessor implements StorageProcessor {
|
|||
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 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);
|
||||
|
||||
try {
|
||||
VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, cmd);
|
||||
|
||||
String templateUuidName = deriveTemplateUuidOnHost(hyperHost, primaryStore.getUuid(), templateInfo.second());
|
||||
|
||||
String storageUuid = managed ? managedStoragePoolName : primaryStore.getUuid();
|
||||
String templateUuidName = deriveTemplateUuidOnHost(hyperHost, storageUuid, templateInfo.second());
|
||||
DatacenterMO dcMo = new DatacenterMO(context, hyperHost.getHyperHostDatacenter());
|
||||
VirtualMachineMO templateMo = VmwareHelper.pickOneVmOnRunningHost(dcMo.findVmByNameAndLabel(templateUuidName), true);
|
||||
DatastoreMO dsMo = null;
|
||||
|
||||
if (templateMo == null) {
|
||||
if (s_logger.isInfoEnabled())
|
||||
s_logger.info("Template " + templateInfo.second() + " is not setup yet, setup template from secondary storage with uuid name: " + templateUuidName);
|
||||
ManagedObjectReference morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, primaryStore.getUuid());
|
||||
assert (morDs != null);
|
||||
DatastoreMO primaryStorageDatastoreMo = new DatastoreMO(context, morDs);
|
||||
if (s_logger.isInfoEnabled()) {
|
||||
s_logger.info("Template " + templateInfo.second() + " is not setup yet. Set up template from secondary storage with uuid name: " + templateUuidName);
|
||||
}
|
||||
|
||||
copyTemplateFromSecondaryToPrimary(hyperHost, primaryStorageDatastoreMo, secondaryStorageUrl, templateInfo.first(), templateInfo.second(),
|
||||
templateUuidName);
|
||||
final ManagedObjectReference morDs;
|
||||
|
||||
if (managed) {
|
||||
morDs = hostService.prepareManagedDatastore(hyperHost, managedStoragePoolName, storageHost, storagePort,
|
||||
chapInitiatorUsername, chapInitiatorSecret, chapTargetUsername, chapTargetSecret);
|
||||
}
|
||||
else {
|
||||
morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, storageUuid);
|
||||
}
|
||||
|
||||
assert (morDs != null);
|
||||
|
||||
dsMo = new DatastoreMO(context, morDs);
|
||||
|
||||
copyTemplateFromSecondaryToPrimary(hyperHost, dsMo, secondaryStorageUrl, templateInfo.first(), templateInfo.second(),
|
||||
managed ? managedStoragePoolRootVolumeName : templateUuidName);
|
||||
|
||||
if (managed) {
|
||||
String[] vmwareLayoutFilePair = VmwareStorageLayoutHelper.getVmdkFilePairDatastorePath(dsMo, managedStoragePoolRootVolumeName, managedStoragePoolRootVolumeName,
|
||||
VmwareStorageLayoutType.VMWARE, false);
|
||||
String[] legacyCloudStackLayoutFilePair = VmwareStorageLayoutHelper.getVmdkFilePairDatastorePath(dsMo, null, managedStoragePoolRootVolumeName,
|
||||
VmwareStorageLayoutType.CLOUDSTACK_LEGACY, false);
|
||||
|
||||
dsMo.moveDatastoreFile(vmwareLayoutFilePair[0], dcMo.getMor(), dsMo.getMor(), legacyCloudStackLayoutFilePair[0], dcMo.getMor(), true);
|
||||
dsMo.moveDatastoreFile(vmwareLayoutFilePair[1], dcMo.getMor(), dsMo.getMor(), legacyCloudStackLayoutFilePair[1], dcMo.getMor(), true);
|
||||
|
||||
String folderToDelete = dsMo.getDatastorePath(managedStoragePoolRootVolumeName, true);
|
||||
dsMo.deleteFolder(folderToDelete, dcMo.getMor());
|
||||
}
|
||||
} else {
|
||||
s_logger.info("Template " + templateInfo.second() + " has already been setup, skip the template setup process in primary storage");
|
||||
}
|
||||
|
||||
TemplateObjectTO newTemplate = new TemplateObjectTO();
|
||||
newTemplate.setPath(templateUuidName);
|
||||
|
||||
if (managed) {
|
||||
String path = dsMo.getDatastorePath(managedStoragePoolRootVolumeName + ".vmdk");
|
||||
|
||||
newTemplate.setPath(path);
|
||||
}
|
||||
else {
|
||||
newTemplate.setPath(templateUuidName);
|
||||
}
|
||||
|
||||
return new CopyCmdAnswer(newTemplate);
|
||||
} catch (Throwable e) {
|
||||
if (e instanceof RemoteException) {
|
||||
|
|
@ -233,7 +310,9 @@ public class VmwareStorageProcessor implements StorageProcessor {
|
|||
}
|
||||
|
||||
String msg = "Unable to copy template to primary storage due to exception:" + VmwareHelper.getExceptionMessage(e);
|
||||
|
||||
s_logger.error(msg, e);
|
||||
|
||||
return new CopyCmdAnswer(msg);
|
||||
}
|
||||
}
|
||||
|
|
@ -1176,9 +1255,9 @@ public class VmwareStorageProcessor implements StorageProcessor {
|
|||
Map<String, String> details = disk.getDetails();
|
||||
|
||||
morDs = hostService.prepareManagedStorage(hyperHost, iScsiName, storageHost, storagePort,
|
||||
details.get(DiskTO.CHAP_INITIATOR_USERNAME), details.get(DiskTO.CHAP_INITIATOR_SECRET),
|
||||
details.get(DiskTO.CHAP_TARGET_USERNAME), details.get(DiskTO.CHAP_TARGET_SECRET),
|
||||
volumeTO.getSize(), cmd);
|
||||
details.get(DiskTO.CHAP_INITIATOR_USERNAME), details.get(DiskTO.CHAP_INITIATOR_SECRET),
|
||||
details.get(DiskTO.CHAP_TARGET_USERNAME), details.get(DiskTO.CHAP_TARGET_SECRET),
|
||||
volumeTO.getSize(), cmd);
|
||||
}
|
||||
else {
|
||||
morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, isManaged ? VmwareResource.getDatastoreName(iScsiName) : primaryStore.getUuid());
|
||||
|
|
@ -1572,15 +1651,15 @@ public class VmwareStorageProcessor implements StorageProcessor {
|
|||
VirtualDiskFlatVer2BackingInfo backingInfo = (VirtualDiskFlatVer2BackingInfo)virtualDisk.getBacking();
|
||||
String path = backingInfo.getFileName();
|
||||
|
||||
path = new DatastoreFile(path).getFileBaseName();
|
||||
|
||||
String search = "-";
|
||||
String search = "[-";
|
||||
int index = path.indexOf(search);
|
||||
|
||||
if (index > -1) {
|
||||
path = path.substring(index + search.length());
|
||||
|
||||
index = path.lastIndexOf(search);
|
||||
String search2 = "-0]";
|
||||
|
||||
index = path.lastIndexOf(search2);
|
||||
|
||||
if (index > -1) {
|
||||
path = path.substring(0, index);
|
||||
|
|
|
|||
|
|
@ -911,7 +911,7 @@ public class XenServerStorageProcessor implements StorageProcessor {
|
|||
String chapInitiatorSecret = null;
|
||||
|
||||
if (destDataStoreTo instanceof PrimaryDataStoreTO) {
|
||||
PrimaryDataStoreTO destPrimaryDataStoreTo = (PrimaryDataStoreTO) destDataStoreTo;
|
||||
PrimaryDataStoreTO destPrimaryDataStoreTo = (PrimaryDataStoreTO)destDataStoreTo;
|
||||
|
||||
Map<String, String> details = destPrimaryDataStoreTo.getDetails();
|
||||
|
||||
|
|
|
|||
|
|
@ -142,6 +142,23 @@ public class DatastoreMO extends BaseMO {
|
|||
return path;
|
||||
}
|
||||
|
||||
public boolean deleteFolder(String folder, ManagedObjectReference morDc) throws Exception {
|
||||
ManagedObjectReference morFileManager = _context.getServiceContent().getFileManager();
|
||||
ManagedObjectReference morTask = _context.getService().deleteDatastoreFileTask(morFileManager, folder, morDc);
|
||||
|
||||
boolean result = _context.getVimClient().waitForTask(morTask);
|
||||
|
||||
if (result) {
|
||||
_context.waitForTaskProgressDone(morTask);
|
||||
|
||||
return true;
|
||||
} else {
|
||||
s_logger.error("VMware deleteDatastoreFile_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean deleteFile(String path, ManagedObjectReference morDc, boolean testExistence) throws Exception {
|
||||
String datastoreName = getName();
|
||||
ManagedObjectReference morFileManager = _context.getServiceContent().getFileManager();
|
||||
|
|
|
|||
Loading…
Reference in New Issue