mirror of https://github.com/apache/cloudstack.git
multi local storage handling for kvm (#6699)
Co-authored-by: DK101010 <dirk.klahre@itelligence.de> Co-authored-by: João Jandre <48719461+JoaoJandre@users.noreply.github.com>
This commit is contained in:
parent
0735b91037
commit
6001772335
|
|
@ -52,6 +52,13 @@ public class StoragePoolInfo {
|
|||
this.details = details;
|
||||
}
|
||||
|
||||
public StoragePoolInfo(String uuid, String host, String hostPath, String localPath, StoragePoolType poolType, long capacityBytes, long availableBytes,
|
||||
Map<String, String> details, String name) {
|
||||
this(uuid, host, hostPath, localPath, poolType, capacityBytes, availableBytes);
|
||||
this.details = details;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public long getCapacityBytes() {
|
||||
return capacityBytes;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -119,6 +119,10 @@ public class ListHostsCmd extends BaseListCmd {
|
|||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getHostName() {
|
||||
return hostName;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import org.apache.cloudstack.api.ApiConstants;
|
|||
import org.apache.cloudstack.api.BaseListCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.response.ClusterResponse;
|
||||
import org.apache.cloudstack.api.response.HostResponse;
|
||||
import org.apache.cloudstack.api.response.ListResponse;
|
||||
import org.apache.cloudstack.api.response.PodResponse;
|
||||
import org.apache.cloudstack.api.response.StoragePoolResponse;
|
||||
|
|
@ -63,16 +64,25 @@ public class ListStoragePoolsCmd extends BaseListCmd {
|
|||
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = StoragePoolResponse.class, description = "the ID of the storage pool")
|
||||
private Long id;
|
||||
|
||||
@Parameter(name = ApiConstants.SCOPE, type = CommandType.STRING, entityType = StoragePoolResponse.class, description = "the ID of the storage pool")
|
||||
@Parameter(name = ApiConstants.SCOPE, type = CommandType.STRING, entityType = StoragePoolResponse.class, description = "the scope of the storage pool")
|
||||
private String scope;
|
||||
|
||||
|
||||
@Parameter(name = ApiConstants.STATUS, type = CommandType.STRING, description = "the status of the storage pool")
|
||||
private String status;
|
||||
|
||||
@Parameter(name = ApiConstants.HOST_ID, type = CommandType.UUID, entityType = HostResponse.class, description = "host ID of the storage pools")
|
||||
private Long hostId;
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public Long getHostId() {
|
||||
return hostId;
|
||||
}
|
||||
|
||||
public Long getClusterId() {
|
||||
return clusterId;
|
||||
}
|
||||
|
|
@ -81,6 +91,10 @@ public class ListStoragePoolsCmd extends BaseListCmd {
|
|||
return ipAddress;
|
||||
}
|
||||
|
||||
public void setIpAddress(String ipAddress) {
|
||||
this.ipAddress = ipAddress;
|
||||
}
|
||||
|
||||
public String getStoragePoolName() {
|
||||
return storagePoolName;
|
||||
}
|
||||
|
|
@ -108,6 +122,15 @@ public class ListStoragePoolsCmd extends BaseListCmd {
|
|||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getScope() {
|
||||
return scope;
|
||||
}
|
||||
|
||||
public void setScope(String scope) {
|
||||
this.scope = scope;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -123,8 +146,4 @@ public class ListStoragePoolsCmd extends BaseListCmd {
|
|||
response.setResponseName(getCommandName());
|
||||
this.setResponseObject(response);
|
||||
}
|
||||
|
||||
public String getScope() {
|
||||
return scope;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ import com.cloud.agent.api.ValidateVcenterDetailsCommand;
|
|||
import com.cloud.alert.AlertManager;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.exception.StorageConflictException;
|
||||
import com.cloud.exception.StorageUnavailableException;
|
||||
import com.cloud.host.Host;
|
||||
import com.cloud.host.HostVO;
|
||||
import com.cloud.host.dao.HostDao;
|
||||
|
|
@ -44,7 +45,6 @@ import com.cloud.storage.dao.StoragePoolWorkDao;
|
|||
import com.cloud.storage.dao.VolumeDao;
|
||||
import com.cloud.user.dao.UserDao;
|
||||
import com.cloud.utils.NumbersUtil;
|
||||
import com.cloud.utils.UriUtils;
|
||||
import com.cloud.utils.db.DB;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.vm.VirtualMachineManager;
|
||||
|
|
@ -67,10 +67,6 @@ import org.apache.cloudstack.storage.volume.datastore.PrimaryDataStoreHelper;
|
|||
import org.apache.log4j.Logger;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URLDecoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
|
@ -138,64 +134,26 @@ public class CloudStackPrimaryDataStoreLifeCycleImpl implements PrimaryDataStore
|
|||
|
||||
PrimaryDataStoreParameters parameters = new PrimaryDataStoreParameters();
|
||||
|
||||
UriUtils.UriInfo uriInfo = UriUtils.getUriInfo(url);
|
||||
|
||||
String scheme = uriInfo.getScheme();
|
||||
String storageHost = uriInfo.getStorageHost();
|
||||
String storagePath = uriInfo.getStoragePath();
|
||||
try {
|
||||
if (scheme == null) {
|
||||
throw new InvalidParameterValueException("scheme is null " + url + ", add nfs:// (or cifs://) as a prefix");
|
||||
} else if (scheme.equalsIgnoreCase("nfs")) {
|
||||
if (storageHost == null || storagePath == null || storageHost.trim().isEmpty() || storagePath.trim().isEmpty()) {
|
||||
throw new InvalidParameterValueException("host or path is null, should be nfs://hostname/path");
|
||||
}
|
||||
} else if (scheme.equalsIgnoreCase("cifs")) {
|
||||
// Don't validate against a URI encoded URI.
|
||||
URI cifsUri = new URI(url);
|
||||
String warnMsg = UriUtils.getCifsUriParametersProblems(cifsUri);
|
||||
if (warnMsg != null) {
|
||||
throw new InvalidParameterValueException(warnMsg);
|
||||
}
|
||||
} else if (scheme.equalsIgnoreCase("sharedMountPoint")) {
|
||||
if (storagePath == null) {
|
||||
throw new InvalidParameterValueException("host or path is null, should be sharedmountpoint://localhost/path");
|
||||
}
|
||||
} else if (scheme.equalsIgnoreCase("rbd")) {
|
||||
if (storagePath == null) {
|
||||
throw new InvalidParameterValueException("host or path is null, should be rbd://hostname/pool");
|
||||
}
|
||||
} else if (scheme.equalsIgnoreCase("gluster")) {
|
||||
if (storageHost == null || storagePath == null || storageHost.trim().isEmpty() || storagePath.trim().isEmpty()) {
|
||||
throw new InvalidParameterValueException("host or path is null, should be gluster://hostname/volume");
|
||||
}
|
||||
}
|
||||
} catch (URISyntaxException e) {
|
||||
throw new InvalidParameterValueException(url + " is not a valid uri");
|
||||
}
|
||||
|
||||
String tags = (String)dsInfos.get("tags");
|
||||
Map<String, String> details = (Map<String, String>)dsInfos.get("details");
|
||||
|
||||
parameters.setTags(tags);
|
||||
parameters.setDetails(details);
|
||||
|
||||
String hostPath = null;
|
||||
try {
|
||||
hostPath = URLDecoder.decode(storagePath, "UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
s_logger.error("[ignored] we are on a platform not supporting \"UTF-8\"!?!", e);
|
||||
}
|
||||
if (hostPath == null) { // if decoding fails, use getPath() anyway
|
||||
hostPath = storagePath;
|
||||
}
|
||||
String scheme = dsInfos.get("scheme").toString();
|
||||
String storageHost = dsInfos.get("host").toString();
|
||||
String hostPath = dsInfos.get("hostPath").toString();
|
||||
String uri = String.format("%s://%s%s", scheme, storageHost, hostPath);
|
||||
|
||||
Object localStorage = dsInfos.get("localStorage");
|
||||
if (localStorage != null) {
|
||||
hostPath = hostPath.replaceFirst("/", "");
|
||||
if (localStorage != null) {
|
||||
hostPath = hostPath.contains("//") ? hostPath.replaceFirst("/", "") : hostPath;
|
||||
hostPath = hostPath.replace("+", " ");
|
||||
}
|
||||
String userInfo = uriInfo.getUserInfo();
|
||||
int port = uriInfo.getPort();
|
||||
|
||||
String userInfo = dsInfos.get("userInfo") != null ? dsInfos.get("userInfo").toString() : null;
|
||||
int port = dsInfos.get("port") != null ? Integer.parseInt(dsInfos.get("port").toString()) : -1;
|
||||
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("createPool Params @ scheme - " + scheme + " storageHost - " + storageHost + " hostPath - " + hostPath + " port - " + port);
|
||||
}
|
||||
|
|
@ -312,8 +270,8 @@ public class CloudStackPrimaryDataStoreLifeCycleImpl implements PrimaryDataStore
|
|||
parameters.setPort(0);
|
||||
parameters.setPath(hostPath);
|
||||
} else {
|
||||
s_logger.warn("Unable to figure out the scheme for URI: " + uriInfo);
|
||||
throw new IllegalArgumentException("Unable to figure out the scheme for URI: " + uriInfo);
|
||||
s_logger.warn("Unable to figure out the scheme for URI: " + scheme);
|
||||
throw new IllegalArgumentException("Unable to figure out the scheme for URI: " + scheme);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -321,7 +279,7 @@ public class CloudStackPrimaryDataStoreLifeCycleImpl implements PrimaryDataStore
|
|||
List<StoragePoolVO> pools = primaryDataStoreDao.listPoolByHostPath(storageHost, hostPath);
|
||||
if (!pools.isEmpty() && !scheme.equalsIgnoreCase("sharedmountpoint")) {
|
||||
Long oldPodId = pools.get(0).getPodId();
|
||||
throw new CloudRuntimeException("Storage pool " + uriInfo + " already in use by another pod (id=" + oldPodId + ")");
|
||||
throw new CloudRuntimeException("Storage pool " + hostPath + " already in use by another pod (id=" + oldPodId + ")");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -550,7 +508,16 @@ public class CloudStackPrimaryDataStoreLifeCycleImpl implements PrimaryDataStore
|
|||
|
||||
@Override
|
||||
public boolean attachHost(DataStore store, HostScope scope, StoragePoolInfo existingInfo) {
|
||||
dataStoreHelper.attachHost(store, scope, existingInfo);
|
||||
DataStore dataStore = dataStoreHelper.attachHost(store, scope, existingInfo);
|
||||
if(existingInfo.getCapacityBytes() == 0){
|
||||
try {
|
||||
storageMgr.connectHostToSharedPool(scope.getScopeId(), dataStore.getId());
|
||||
} catch (StorageUnavailableException ex) {
|
||||
s_logger.error("Storage unavailable ",ex);
|
||||
} catch (StorageConflictException ex) {
|
||||
s_logger.error("Storage already exists ",ex);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2793,10 +2793,29 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||
|
||||
@Override
|
||||
public ListResponse<StoragePoolResponse> searchForStoragePools(ListStoragePoolsCmd cmd) {
|
||||
Pair<List<StoragePoolJoinVO>, Integer> result = searchForStoragePoolsInternal(cmd);
|
||||
ListResponse<StoragePoolResponse> response = new ListResponse<StoragePoolResponse>();
|
||||
Pair<List<StoragePoolJoinVO>, Integer> result = cmd.getHostId() != null ? searchForLocalStorages(cmd) : searchForStoragePoolsInternal(cmd);
|
||||
return createStoragesPoolResponse(result);
|
||||
}
|
||||
|
||||
List<StoragePoolResponse> poolResponses = ViewResponseHelper.createStoragePoolResponse(result.first().toArray(new StoragePoolJoinVO[result.first().size()]));
|
||||
private Pair<List<StoragePoolJoinVO>, Integer> searchForLocalStorages(ListStoragePoolsCmd cmd) {
|
||||
long id = cmd.getHostId();
|
||||
String scope = ScopeType.HOST.toString();
|
||||
Pair<List<StoragePoolJoinVO>, Integer> localStorages;
|
||||
|
||||
ListHostsCmd listHostsCmd = new ListHostsCmd();
|
||||
listHostsCmd.setId(id);
|
||||
Pair<List<HostJoinVO>, Integer> hosts = searchForServersInternal(listHostsCmd);
|
||||
|
||||
cmd.setScope(scope);
|
||||
localStorages = searchForStoragePoolsInternal(cmd);
|
||||
|
||||
return localStorages;
|
||||
}
|
||||
|
||||
private ListResponse<StoragePoolResponse> createStoragesPoolResponse(Pair<List<StoragePoolJoinVO>, Integer> storagePools) {
|
||||
ListResponse<StoragePoolResponse> response = new ListResponse<>();
|
||||
|
||||
List<StoragePoolResponse> poolResponses = ViewResponseHelper.createStoragePoolResponse(storagePools.first().toArray(new StoragePoolJoinVO[storagePools.first().size()]));
|
||||
for (StoragePoolResponse poolResponse : poolResponses) {
|
||||
DataStore store = dataStoreManager.getPrimaryDataStore(poolResponse.getId());
|
||||
if (store != null) {
|
||||
|
|
@ -2816,7 +2835,7 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
|
|||
}
|
||||
}
|
||||
|
||||
response.setResponses(poolResponses, result.second());
|
||||
response.setResponses(poolResponses, storagePools.second());
|
||||
return response;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -237,6 +237,9 @@ import com.cloud.vm.VMInstanceVO;
|
|||
import com.cloud.vm.VirtualMachine.State;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
import com.google.common.collect.Sets;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
|
||||
|
||||
@Component
|
||||
public class StorageManagerImpl extends ManagerBase implements StorageManager, ClusterManagerListener, Configurable {
|
||||
|
|
@ -653,6 +656,41 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||
return true;
|
||||
}
|
||||
|
||||
private DataStore createLocalStorage(Map<String, Object> poolInfos) throws ConnectionException{
|
||||
Object existingUuid = poolInfos.get("uuid");
|
||||
if( existingUuid == null ){
|
||||
poolInfos.put("uuid", UUID.randomUUID().toString());
|
||||
}
|
||||
String hostAddress = poolInfos.get("host").toString();
|
||||
Host host = _hostDao.findByName(hostAddress);
|
||||
|
||||
if( host == null ) {
|
||||
host = _hostDao.findByIp(hostAddress);
|
||||
|
||||
if( host == null ) {
|
||||
host = _hostDao.findByPublicIp(hostAddress);
|
||||
|
||||
if( host == null ) {
|
||||
throw new InvalidParameterValueException(String.format("host %s not found",hostAddress));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
long capacityBytes = poolInfos.get("capacityBytes") != null ? Long.parseLong(poolInfos.get("capacityBytes").toString()) : 0;
|
||||
|
||||
StoragePoolInfo pInfo = new StoragePoolInfo(poolInfos.get("uuid").toString(),
|
||||
host.getPrivateIpAddress(),
|
||||
poolInfos.get("hostPath").toString(),
|
||||
poolInfos.get("hostPath").toString(),
|
||||
StoragePoolType.Filesystem,
|
||||
capacityBytes,
|
||||
0,
|
||||
(Map<String,String>)poolInfos.get("details"),
|
||||
poolInfos.get("name").toString());
|
||||
|
||||
return createLocalStorage(host, pInfo);
|
||||
}
|
||||
|
||||
@DB
|
||||
@Override
|
||||
public DataStore createLocalStorage(Host host, StoragePoolInfo pInfo) throws ConnectionException {
|
||||
|
|
@ -698,17 +736,19 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||
DataStoreLifeCycle lifeCycle = provider.getDataStoreLifeCycle();
|
||||
if (pool == null) {
|
||||
Map<String, Object> params = new HashMap<String, Object>();
|
||||
String name = createLocalStoragePoolName(host, pInfo);
|
||||
String name = pInfo.getName() != null ? pInfo.getName() : createLocalStoragePoolName(host, pInfo);
|
||||
params.put("zoneId", host.getDataCenterId());
|
||||
params.put("clusterId", host.getClusterId());
|
||||
params.put("podId", host.getPodId());
|
||||
params.put("hypervisorType", host.getHypervisorType());
|
||||
params.put("url", pInfo.getPoolType().toString() + "://" + pInfo.getHost() + "/" + pInfo.getHostPath());
|
||||
params.put("name", name);
|
||||
params.put("localStorage", true);
|
||||
params.put("details", pInfo.getDetails());
|
||||
params.put("uuid", pInfo.getUuid());
|
||||
params.put("providerName", provider.getName());
|
||||
params.put("scheme", pInfo.getPoolType().toString());
|
||||
params.put("host", pInfo.getHost());
|
||||
params.put("hostPath", pInfo.getHostPath());
|
||||
|
||||
store = lifeCycle.initialize(params);
|
||||
} else {
|
||||
|
|
@ -740,6 +780,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||
@Override
|
||||
public PrimaryDataStoreInfo createPool(CreateStoragePoolCmd cmd) throws ResourceInUseException, IllegalArgumentException, UnknownHostException, ResourceUnavailableException {
|
||||
String providerName = cmd.getStorageProviderName();
|
||||
Map<String,String> uriParams = extractUriParamsAsMap(cmd.getUrl());
|
||||
DataStoreProvider storeProvider = _dataStoreProviderMgr.getDataStoreProvider(providerName);
|
||||
|
||||
if (storeProvider == null) {
|
||||
|
|
@ -753,7 +794,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||
Long podId = cmd.getPodId();
|
||||
Long zoneId = cmd.getZoneId();
|
||||
|
||||
ScopeType scopeType = ScopeType.CLUSTER;
|
||||
ScopeType scopeType = uriParams.get("scheme").toString().equals("file") ? ScopeType.HOST : ScopeType.CLUSTER;
|
||||
String scope = cmd.getScope();
|
||||
if (scope != null) {
|
||||
try {
|
||||
|
|
@ -819,11 +860,16 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||
params.put("managed", cmd.isManaged());
|
||||
params.put("capacityBytes", cmd.getCapacityBytes());
|
||||
params.put("capacityIops", cmd.getCapacityIops());
|
||||
params.putAll(uriParams);
|
||||
|
||||
DataStoreLifeCycle lifeCycle = storeProvider.getDataStoreLifeCycle();
|
||||
DataStore store = null;
|
||||
try {
|
||||
store = lifeCycle.initialize(params);
|
||||
if (params.get("scheme").toString().equals("file")) {
|
||||
store = createLocalStorage(params);
|
||||
} else {
|
||||
store = lifeCycle.initialize(params);
|
||||
}
|
||||
if (scopeType == ScopeType.CLUSTER) {
|
||||
ClusterScope clusterScope = new ClusterScope(clusterId, podId, zoneId);
|
||||
lifeCycle.attachCluster(store, clusterScope);
|
||||
|
|
@ -848,6 +894,62 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||
return (PrimaryDataStoreInfo)_dataStoreMgr.getDataStore(store.getId(), DataStoreRole.Primary);
|
||||
}
|
||||
|
||||
private Map<String,String> extractUriParamsAsMap(String url){
|
||||
Map<String,String> uriParams = new HashMap<>();
|
||||
UriUtils.UriInfo uriInfo = UriUtils.getUriInfo(url);
|
||||
|
||||
String scheme = uriInfo.getScheme();
|
||||
String storageHost = uriInfo.getStorageHost();
|
||||
String storagePath = uriInfo.getStoragePath();
|
||||
try {
|
||||
if (scheme == null) {
|
||||
throw new InvalidParameterValueException("scheme is null " + url + ", add nfs:// (or cifs://) as a prefix");
|
||||
} else if (scheme.equalsIgnoreCase("nfs")) {
|
||||
if (storageHost == null || storagePath == null || storageHost.trim().isEmpty() || storagePath.trim().isEmpty()) {
|
||||
throw new InvalidParameterValueException("host or path is null, should be nfs://hostname/path");
|
||||
}
|
||||
} else if (scheme.equalsIgnoreCase("cifs")) {
|
||||
// Don't validate against a URI encoded URI.
|
||||
URI cifsUri = new URI(url);
|
||||
String warnMsg = UriUtils.getCifsUriParametersProblems(cifsUri);
|
||||
if (warnMsg != null) {
|
||||
throw new InvalidParameterValueException(warnMsg);
|
||||
}
|
||||
} else if (scheme.equalsIgnoreCase("sharedMountPoint")) {
|
||||
if (storagePath == null) {
|
||||
throw new InvalidParameterValueException("host or path is null, should be sharedmountpoint://localhost/path");
|
||||
}
|
||||
} else if (scheme.equalsIgnoreCase("rbd")) {
|
||||
if (storagePath == null) {
|
||||
throw new InvalidParameterValueException("host or path is null, should be rbd://hostname/pool");
|
||||
}
|
||||
} else if (scheme.equalsIgnoreCase("gluster")) {
|
||||
if (storageHost == null || storagePath == null || storageHost.trim().isEmpty() || storagePath.trim().isEmpty()) {
|
||||
throw new InvalidParameterValueException("host or path is null, should be gluster://hostname/volume");
|
||||
}
|
||||
}
|
||||
} catch (URISyntaxException e) {
|
||||
throw new InvalidParameterValueException(url + " is not a valid uri");
|
||||
}
|
||||
|
||||
String hostPath = null;
|
||||
try {
|
||||
hostPath = URLDecoder.decode(storagePath, "UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
s_logger.error("[ignored] we are on a platform not supporting \"UTF-8\"!?!", e);
|
||||
}
|
||||
if (hostPath == null) { // if decoding fails, use getPath() anyway
|
||||
hostPath = storagePath;
|
||||
}
|
||||
|
||||
uriParams.put("scheme", scheme);
|
||||
uriParams.put("host", storageHost);
|
||||
uriParams.put("hostPath", hostPath);
|
||||
uriParams.put("userInfo", uriInfo.getUserInfo());
|
||||
uriParams.put("port", uriInfo.getPort() + "");
|
||||
return uriParams;
|
||||
}
|
||||
|
||||
private Map<String, String> extractApiParamAsMap(Map ds) {
|
||||
Map<String, String> details = new HashMap<String, String>();
|
||||
if (ds != null) {
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
<a-select
|
||||
v-model:value="form.scope"
|
||||
v-focus="true"
|
||||
@change="val => changeScope(val)"
|
||||
showSearch
|
||||
optionFilterProp="label"
|
||||
:filterOption="(input, option) => {
|
||||
|
|
@ -40,6 +41,7 @@
|
|||
:placeholder="apiParams.scope.description" >
|
||||
<a-select-option :value="'cluster'" :label="$t('label.clusterid')"> {{ $t('label.clusterid') }} </a-select-option>
|
||||
<a-select-option :value="'zone'" :label="$t('label.zoneid')"> {{ $t('label.zoneid') }} </a-select-option>
|
||||
<a-select-option :value="'host'" :label="$t('label.hostid')"> {{ $t('label.hostid') }} </a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<div v-if="form.scope === 'zone'">
|
||||
|
|
@ -168,7 +170,7 @@
|
|||
<a-input v-model:value="form.server" :placeholder="$t('message.server.description')" />
|
||||
</a-form-item>
|
||||
</div>
|
||||
<div v-if="form.protocol === 'nfs' || form.protocol === 'SMB' || form.protocol === 'ocfs2' || (form.protocol === 'PreSetup' && hypervisorType !== 'VMware') || form.protocol === 'SharedMountPoint'">
|
||||
<div v-if="form.protocol === 'nfs' || form.protocol === 'SMB' || form.protocol === 'ocfs2' || form.protocol === 'Filesystem' || (form.protocol === 'PreSetup' && hypervisorType !== 'VMware') || form.protocol === 'SharedMountPoint'">
|
||||
<a-form-item name="path" ref="path">
|
||||
<template #label>
|
||||
<tooltip-label :title="$t('label.path')" :tooltip="$t('message.path.description')"/>
|
||||
|
|
@ -438,6 +440,15 @@ export default {
|
|||
this.loading = false
|
||||
})
|
||||
},
|
||||
changeScope (value) {
|
||||
if (value === 'host') {
|
||||
const cluster = this.clusters.find(cluster => cluster.id === this.form.cluster)
|
||||
this.hypervisorType = cluster.hypervisortype
|
||||
if (this.hypervisorType === 'KVM') {
|
||||
this.protocols.push('Filesystem')
|
||||
}
|
||||
}
|
||||
},
|
||||
changeZone (value) {
|
||||
this.form.zone = value
|
||||
if (this.form.zone === '') {
|
||||
|
|
@ -504,6 +515,9 @@ export default {
|
|||
this.hypervisorType = cluster.hypervisortype
|
||||
if (this.hypervisorType === 'KVM') {
|
||||
this.protocols = ['nfs', 'SharedMountPoint', 'RBD', 'CLVM', 'Gluster', 'Linstor', 'custom']
|
||||
if (this.form.scope === 'host') {
|
||||
this.protocols.push('Filesystem')
|
||||
}
|
||||
} else if (this.hypervisorType === 'XenServer') {
|
||||
this.protocols = ['nfs', 'PreSetup', 'iscsi', 'custom']
|
||||
} else if (this.hypervisorType === 'VMware') {
|
||||
|
|
@ -524,6 +538,20 @@ export default {
|
|||
this.form.protocol = this.protocols[0]
|
||||
}
|
||||
},
|
||||
filesystemURL (hostId, path) {
|
||||
var url
|
||||
if (path.substring(0, 1) !== '/') {
|
||||
path = '/' + path
|
||||
}
|
||||
var hostName
|
||||
this.hosts.forEach(host => {
|
||||
if (host.id === hostId) {
|
||||
hostName = host.name
|
||||
}
|
||||
})
|
||||
url = 'file://' + hostName + path
|
||||
return url
|
||||
},
|
||||
nfsURL (server, path) {
|
||||
var url
|
||||
if (path.substring(0, 1) !== '/') {
|
||||
|
|
@ -756,6 +784,8 @@ export default {
|
|||
if (values.capacityIops && values.capacityIops.length > 0) {
|
||||
params.capacityIops = values.capacityIops.split(',').join('')
|
||||
}
|
||||
} else if (values.protocol === 'Filesystem') {
|
||||
url = this.filesystemURL(values.host, path)
|
||||
}
|
||||
params.url = url
|
||||
if (values.provider !== 'DefaultPrimary' && values.provider !== 'PowerFlex') {
|
||||
|
|
|
|||
Loading…
Reference in New Issue