mirror of
https://github.com/apache/cloudstack.git
synced 2025-12-17 02:53:18 +01:00
NFS support for VMware-managed storage
Signed-off-by: Mike Tutkowski <mike.tutkowski@solidfire.com>
This commit is contained in:
parent
8e5fefc66c
commit
ff7ef985f1
@ -2360,7 +2360,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
||||
// if the datastore is not present, we need to discover the iSCSI device that will support it,
|
||||
// create the datastore, and create a VMDK file in the datastore
|
||||
if (morDatastore == null) {
|
||||
morDatastore = _storageProcessor.prepareManagedStorage(context, hyperHost, iScsiName,
|
||||
morDatastore = _storageProcessor.prepareManagedStorage(context, hyperHost, null, iScsiName,
|
||||
details.get(DiskTO.STORAGE_HOST), Integer.parseInt(details.get(DiskTO.STORAGE_PORT)),
|
||||
volumeTO.getVolumeType() == Volume.Type.ROOT ? volumeTO.getName() : null,
|
||||
details.get(DiskTO.CHAP_INITIATOR_USERNAME), details.get(DiskTO.CHAP_INITIATOR_SECRET),
|
||||
|
||||
@ -105,6 +105,7 @@ import com.cloud.vm.VirtualMachine.PowerState;
|
||||
|
||||
public class VmwareStorageProcessor implements StorageProcessor {
|
||||
private static final Logger s_logger = Logger.getLogger(VmwareStorageProcessor.class);
|
||||
private static final int DEFAULT_NFS_PORT = 2049;
|
||||
|
||||
private VmwareHostService hostService;
|
||||
private boolean _fullCloneFlag;
|
||||
@ -297,8 +298,8 @@ public class VmwareStorageProcessor implements StorageProcessor {
|
||||
final ManagedObjectReference morDs;
|
||||
|
||||
if (managed) {
|
||||
morDs = prepareManagedDatastore(context, hyperHost, managedStoragePoolName, storageHost, storagePort,
|
||||
chapInitiatorUsername, chapInitiatorSecret, chapTargetUsername, chapTargetSecret);
|
||||
morDs = prepareManagedDatastore(context, hyperHost, null, managedStoragePoolName, storageHost, storagePort,
|
||||
chapInitiatorUsername, chapInitiatorSecret, chapTargetUsername, chapTargetSecret);
|
||||
}
|
||||
else {
|
||||
morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, storageUuid);
|
||||
@ -1306,17 +1307,22 @@ public class VmwareStorageProcessor implements StorageProcessor {
|
||||
vmName = vmMo.getName();
|
||||
|
||||
ManagedObjectReference morDs = null;
|
||||
String diskUuid = volumeTO.getUuid().replace("-", "");
|
||||
|
||||
if (isAttach && isManaged) {
|
||||
Map<String, String> details = disk.getDetails();
|
||||
|
||||
morDs = prepareManagedStorage(context, hyperHost, iScsiName, storageHost, storagePort, null,
|
||||
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);
|
||||
morDs = prepareManagedStorage(context, hyperHost, diskUuid, iScsiName, storageHost, storagePort, null,
|
||||
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());
|
||||
if (storagePort == DEFAULT_NFS_PORT) {
|
||||
morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, isManaged ? VmwareResource.getDatastoreName(diskUuid) : primaryStore.getUuid());
|
||||
} else {
|
||||
morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, isManaged ? VmwareResource.getDatastoreName(iScsiName) : primaryStore.getUuid());
|
||||
}
|
||||
}
|
||||
|
||||
if (morDs == null) {
|
||||
@ -1357,7 +1363,7 @@ public class VmwareStorageProcessor implements StorageProcessor {
|
||||
vmMo.detachDisk(datastoreVolumePath, false);
|
||||
|
||||
if (isManaged) {
|
||||
handleDatastoreAndVmdkDetach(iScsiName, storageHost, storagePort);
|
||||
handleDatastoreAndVmdkDetachManaged(diskUuid, iScsiName, storageHost, storagePort);
|
||||
} else {
|
||||
VmwareStorageLayoutHelper.syncVolumeToRootFolder(dsMo.getOwnerDatacenter().first(), dsMo, volumeTO.getPath());
|
||||
}
|
||||
@ -1721,11 +1727,24 @@ public class VmwareStorageProcessor implements StorageProcessor {
|
||||
return getVmfsDatastore(context, hyperHost, datastoreName, storageHost, storagePort, trimIqn(iScsiName), null, null, null, null);
|
||||
}
|
||||
|
||||
private ManagedObjectReference prepareManagedDatastore(VmwareContext context, VmwareHypervisorHost hyperHost, String iScsiName,
|
||||
String storageHost, int storagePort, String chapInitiatorUsername, String chapInitiatorSecret,
|
||||
String chapTargetUsername, String chapTargetSecret) throws Exception {
|
||||
return getVmfsDatastore(context, hyperHost, VmwareResource.getDatastoreName(iScsiName), storageHost, storagePort,
|
||||
trimIqn(iScsiName), chapInitiatorUsername, chapInitiatorSecret, chapTargetUsername, chapTargetSecret);
|
||||
private ManagedObjectReference prepareManagedDatastore(VmwareContext context, VmwareHypervisorHost hyperHost, String diskUuid, String iScsiName,
|
||||
String storageHost, int storagePort, String chapInitiatorUsername, String chapInitiatorSecret,
|
||||
String chapTargetUsername, String chapTargetSecret) throws Exception {
|
||||
if (storagePort == DEFAULT_NFS_PORT) {
|
||||
s_logger.info("creating the NFS datastore with the following configuration - storageHost: " + storageHost + ", storagePort: " + storagePort +
|
||||
", exportpath: " + iScsiName + "and diskUuid : " + diskUuid);
|
||||
ManagedObjectReference morCluster = hyperHost.getHyperHostCluster();
|
||||
ClusterMO cluster = new ClusterMO(context, morCluster);
|
||||
List<Pair<ManagedObjectReference, String>> lstHosts = cluster.getClusterHosts();
|
||||
|
||||
HostMO host = new HostMO(context, lstHosts.get(0).first());
|
||||
HostDatastoreSystemMO hostDatastoreSystem = host.getHostDatastoreSystemMO();
|
||||
|
||||
return hostDatastoreSystem.createNfsDatastore(storageHost, storagePort, iScsiName, diskUuid);
|
||||
} else {
|
||||
return getVmfsDatastore(context, hyperHost, VmwareResource.getDatastoreName(iScsiName), storageHost, storagePort,
|
||||
trimIqn(iScsiName), chapInitiatorUsername, chapInitiatorSecret, chapTargetUsername, chapTargetSecret);
|
||||
}
|
||||
}
|
||||
|
||||
private ManagedObjectReference getVmfsDatastore(VmwareContext context, VmwareHypervisorHost hyperHost, String datastoreName, String storageIpAddress, int storagePortNumber,
|
||||
@ -2006,10 +2025,11 @@ public class VmwareStorageProcessor implements StorageProcessor {
|
||||
return tmp[1].trim();
|
||||
}
|
||||
|
||||
public ManagedObjectReference prepareManagedStorage(VmwareContext context, VmwareHypervisorHost hyperHost, String iScsiName,
|
||||
public ManagedObjectReference prepareManagedStorage(VmwareContext context, VmwareHypervisorHost hyperHost, String diskUuid, String iScsiName,
|
||||
String storageHost, int storagePort, String volumeName, String chapInitiatorUsername, String chapInitiatorSecret,
|
||||
String chapTargetUsername, String chapTargetSecret, long size, Command cmd) throws Exception {
|
||||
ManagedObjectReference morDs = prepareManagedDatastore(context, hyperHost, iScsiName, storageHost, storagePort,
|
||||
|
||||
ManagedObjectReference morDs = prepareManagedDatastore(context, hyperHost, diskUuid, iScsiName, storageHost, storagePort,
|
||||
chapInitiatorUsername, chapInitiatorSecret, chapTargetUsername, chapTargetSecret);
|
||||
|
||||
DatastoreMO dsMo = new DatastoreMO(hostService.getServiceContext(null), morDs);
|
||||
@ -2030,8 +2050,15 @@ public class VmwareStorageProcessor implements StorageProcessor {
|
||||
removeVmfsDatastore(hyperHost, datastoreName, storageHost, storagePort, trimIqn(iqn));
|
||||
}
|
||||
|
||||
private void handleDatastoreAndVmdkDetach(String iqn, String storageHost, int storagePort) throws Exception {
|
||||
handleDatastoreAndVmdkDetach(VmwareResource.getDatastoreName(iqn), iqn, storageHost, storagePort);
|
||||
private void handleDatastoreAndVmdkDetachManaged(String diskUuid, String iqn, String storageHost, int storagePort) throws Exception {
|
||||
if (storagePort == DEFAULT_NFS_PORT) {
|
||||
VmwareContext context = hostService.getServiceContext(null);
|
||||
VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, null);
|
||||
// for managed NFS datastore
|
||||
hyperHost.unmountDatastore(diskUuid);
|
||||
} else {
|
||||
handleDatastoreAndVmdkDetach(VmwareResource.getDatastoreName(iqn), iqn, storageHost, storagePort);
|
||||
}
|
||||
}
|
||||
|
||||
private void removeManagedTargetsFromCluster(List<String> iqns) throws Exception {
|
||||
|
||||
@ -19,22 +19,24 @@
|
||||
|
||||
package org.apache.cloudstack.storage.datastore.driver;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.ChapInfo;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreCapabilities;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
|
||||
import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
|
||||
import org.apache.cloudstack.storage.command.CommandResult;
|
||||
import org.apache.cloudstack.storage.command.CreateObjectAnswer;
|
||||
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
||||
import org.apache.cloudstack.storage.datastore.util.ElastistorUtil;
|
||||
@ -46,7 +48,6 @@ import com.cloud.agent.api.Answer;
|
||||
import com.cloud.agent.api.to.DataObjectType;
|
||||
import com.cloud.agent.api.to.DataStoreTO;
|
||||
import com.cloud.agent.api.to.DataTO;
|
||||
import com.cloud.host.Host;
|
||||
import com.cloud.storage.DiskOfferingVO;
|
||||
import com.cloud.storage.ResizeVolumePayload;
|
||||
import com.cloud.storage.Storage.StoragePoolType;
|
||||
@ -176,7 +177,7 @@ public class ElastistorPrimaryDataStoreDriver extends CloudStackPrimaryDataStore
|
||||
_volumeDao.update(volume.getId(), volume);
|
||||
|
||||
// create new volume details for the volume
|
||||
updateVolumeDetails(volume, esvolume);
|
||||
//updateVolumeDetails(volume, esvolume);
|
||||
|
||||
long capacityBytes = storagePool.getCapacityBytes();
|
||||
long usedBytes = storagePool.getUsedBytes();
|
||||
@ -373,9 +374,14 @@ public class ElastistorPrimaryDataStoreDriver extends CloudStackPrimaryDataStore
|
||||
throw new CloudRuntimeException("elastistor volume snapshot failed");
|
||||
}else{
|
||||
s_logger.info("elastistor volume snapshot succesfull");
|
||||
result = new CreateCmdResult(null, null);
|
||||
result.setSuccess(answer.getResult());
|
||||
result.setAnswer(answer);
|
||||
|
||||
snapshotTO.setPath(answer.getDetails());
|
||||
|
||||
CreateObjectAnswer createObjectAnswer = new CreateObjectAnswer(snapshotTO);
|
||||
|
||||
result = new CreateCmdResult(null, createObjectAnswer);
|
||||
|
||||
result.setResult(null);
|
||||
}
|
||||
}
|
||||
catch (Throwable e) {
|
||||
@ -393,20 +399,11 @@ public class ElastistorPrimaryDataStoreDriver extends CloudStackPrimaryDataStore
|
||||
|
||||
@Override
|
||||
public Map<String, String> getCapabilities() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
Map<String, String> mapCapabilities = new HashMap<String, String>();
|
||||
|
||||
@Override
|
||||
public boolean grantAccess(DataObject dataObject, Host host, DataStore dataStore) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void revokeAccess(DataObject dataObject, Host host, DataStore dataStore) {
|
||||
// TODO Auto-generated method stub
|
||||
mapCapabilities.put(DataStoreCapabilities.STORAGE_SYSTEM_SNAPSHOT.toString(), Boolean.TRUE.toString());
|
||||
|
||||
return mapCapabilities;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -113,6 +113,8 @@ public class ElastistorUtil {
|
||||
public static final String REST_PARAM_AUTHNETWORK = "authnetwork";
|
||||
public static final String REST_PARAM_MAPUSERSTOROOT = "mapuserstoroot";
|
||||
public static final String REST_PARAM_STORAGEID = "storageid";
|
||||
public static final String REST_PARAM_TPCONTROL = "tpcontrol";
|
||||
public static final String REST_PARAM_IOPSCONTROL = "iopscontrol";
|
||||
|
||||
/**
|
||||
* Constants related to elastistor which are persisted in cloudstack
|
||||
@ -165,6 +167,8 @@ public class ElastistorUtil {
|
||||
private static final String ES_AUTHNETWORK_VAL = "all";
|
||||
private static final String ES_MAPUSERSTOROOT_VAL = "yes";
|
||||
private static final String ES_SYNC_VAL = "always";
|
||||
private static final String ES_TPCONTROL_VAL = "false";
|
||||
private static final String ES_IOPSCONTROL_VAL = "true";
|
||||
|
||||
/**
|
||||
* Private constructor s.t. its never instantiated.
|
||||
@ -338,7 +342,8 @@ public class ElastistorUtil {
|
||||
String qosgroupid;
|
||||
String VolumeName = volumeName;
|
||||
String totaliops = String.valueOf(capacityIops);
|
||||
String totalthroughput = String.valueOf(capacityIops * 4);
|
||||
//String totalthroughput = String.valueOf(capacityIops * 4);
|
||||
String totalthroughput = "0";
|
||||
|
||||
String quotasize = convertCapacityBytes(capacityBytes);
|
||||
|
||||
@ -367,6 +372,10 @@ public class ElastistorUtil {
|
||||
addQosGroupCmd.putCommandParameter(ElastistorUtil.REST_PARAM_DATASETID, datasetid);
|
||||
if (null != ElastistorUtil.ES_GRACEALLOWED_VAL)
|
||||
addQosGroupCmd.putCommandParameter(ElastistorUtil.REST_PARAM_GRACEALLOWED, ElastistorUtil.ES_GRACEALLOWED_VAL);
|
||||
if (null != ElastistorUtil.ES_IOPSCONTROL_VAL)
|
||||
addQosGroupCmd.putCommandParameter(ElastistorUtil.REST_PARAM_IOPSCONTROL, ElastistorUtil.ES_IOPSCONTROL_VAL);
|
||||
if (null != ElastistorUtil.ES_TPCONTROL_VAL)
|
||||
addQosGroupCmd.putCommandParameter(ElastistorUtil.REST_PARAM_TPCONTROL, ElastistorUtil.ES_TPCONTROL_VAL);
|
||||
|
||||
AddQosGroupCmdResponse addQosGroupCmdResponse = (AddQosGroupCmdResponse) getElastistorRestClient().executeCommand(addQosGroupCmd);
|
||||
|
||||
@ -2423,7 +2432,7 @@ public class ElastistorUtil {
|
||||
CreateStorageSnapshotCmdResponse snapshotCmdResponse = (CreateStorageSnapshotCmdResponse) getElastistorRestClient().executeCommand(snapshotCmd);
|
||||
|
||||
if(snapshotCmdResponse.getStorageSnapshot().getId() != null){
|
||||
return new Answer(null, true, "snapshot succesfully taken");
|
||||
return new Answer(null, true, snapshotCmdResponse.getStorageSnapshot().getId());
|
||||
}else{
|
||||
return new Answer(null, false, "snapshot failed");
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user