Add Datastore cluster and the child entities which are datastores in the cluster into CloudStack

Setting scope is still pending.
This commit is contained in:
Harikrishna Patnala 2020-07-19 15:36:39 +05:30
parent f858387b3c
commit 41b3fc19d6
8 changed files with 179 additions and 22 deletions

View File

@ -28,6 +28,7 @@ public class StoragePoolInfo {
StoragePoolType poolType;
long capacityBytes;
long availableBytes;
String name;
Map<String, String> details;
protected StoragePoolInfo() {
@ -67,14 +68,34 @@ public class StoragePoolInfo {
return host;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void setLocalPath(String localPath) {
this.localPath = localPath;
}
public String getLocalPath() {
return localPath;
}
public void setHostPath(String hostPath) {
this.hostPath = hostPath;
}
public String getHostPath() {
return hostPath;
}
public void setPoolType(StoragePoolType poolType) {
this.poolType = poolType;
}
public StoragePoolType getPoolType() {
return poolType;
}

View File

@ -19,6 +19,7 @@
package com.cloud.agent.api;
import java.util.List;
import java.util.Map;
import com.cloud.storage.template.TemplateProp;
@ -28,6 +29,7 @@ public class ModifyStoragePoolAnswer extends Answer {
private Map<String, TemplateProp> templateInfo;
private String localDatastoreName;
private String poolType;
private List<ModifyStoragePoolAnswer> datastoreClusterChildren;
public ModifyStoragePoolAnswer(ModifyStoragePoolCommand cmd, long capacityBytes, long availableBytes, Map<String, TemplateProp> tInfo) {
super(cmd);
@ -63,7 +65,6 @@ public class ModifyStoragePoolAnswer extends Answer {
return localDatastoreName;
}
public String getPoolType() {
return poolType;
}
@ -71,4 +72,12 @@ public class ModifyStoragePoolAnswer extends Answer {
public void setPoolType(String poolType) {
this.poolType = poolType;
}
public List<ModifyStoragePoolAnswer> getDatastoreClusterChildren() {
return datastoreClusterChildren;
}
public void setDatastoreClusterChildren(List<ModifyStoragePoolAnswer> datastoreClusterChildren) {
this.datastoreClusterChildren = datastoreClusterChildren;
}
}

View File

@ -22,12 +22,15 @@ import com.cloud.agent.AgentManager;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.ModifyStoragePoolAnswer;
import com.cloud.agent.api.ModifyStoragePoolCommand;
import com.cloud.agent.api.StoragePoolInfo;
import com.cloud.alert.AlertManager;
import com.cloud.exception.StorageConflictException;
import com.cloud.storage.DataStoreRole;
import com.cloud.storage.StoragePool;
import com.cloud.storage.StoragePoolHostVO;
import com.cloud.storage.StoragePoolStatus;
import com.cloud.storage.dao.StoragePoolHostDao;
import com.cloud.storage.dao.StoragePoolTagsDao;
import com.cloud.utils.exception.CloudRuntimeException;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
import org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener;
@ -39,7 +42,9 @@ import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import javax.inject.Inject;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class DefaultHostListener implements HypervisorHostListener {
private static final Logger s_logger = Logger.getLogger(DefaultHostListener.class);
@ -55,6 +60,8 @@ public class DefaultHostListener implements HypervisorHostListener {
PrimaryDataStoreDao primaryStoreDao;
@Inject
StoragePoolDetailsDao storagePoolDetailsDao;
@Inject
StoragePoolTagsDao storagePoolTagsDao;
@Override
public boolean hostAdded(long hostId) {
@ -92,7 +99,52 @@ public class DefaultHostListener implements HypervisorHostListener {
}
}
}
StoragePoolVO poolVO = this.primaryStoreDao.findById(poolId);
updateStoragePoolHostVOAndDetails(poolVO, hostId, mspAnswer);
for (ModifyStoragePoolAnswer childDataStoreAnswer : ((ModifyStoragePoolAnswer) answer).getDatastoreClusterChildren()) {
StoragePoolInfo childStoragePoolInfo = childDataStoreAnswer.getPoolInfo();
StoragePoolVO dataStoreVO = primaryStoreDao.findPoolByUUID(childStoragePoolInfo.getUuid());
if (dataStoreVO != null) {
continue;
}
dataStoreVO = new StoragePoolVO();
dataStoreVO.setStorageProviderName(poolVO.getStorageProviderName());
dataStoreVO.setHostAddress(childStoragePoolInfo.getHost());
dataStoreVO.setPoolType(poolVO.getPoolType());
dataStoreVO.setPath(childStoragePoolInfo.getHostPath());
dataStoreVO.setPort(poolVO.getPort());
dataStoreVO.setName(childStoragePoolInfo.getName());
dataStoreVO.setUuid(childStoragePoolInfo.getUuid());
dataStoreVO.setDataCenterId(poolVO.getDataCenterId());
dataStoreVO.setPodId(poolVO.getPodId());
dataStoreVO.setClusterId(poolVO.getClusterId());
dataStoreVO.setStatus(StoragePoolStatus.Up);
dataStoreVO.setUserInfo(poolVO.getUserInfo());
dataStoreVO.setManaged(poolVO.isManaged());
dataStoreVO.setCapacityIops(poolVO.getCapacityIops());
dataStoreVO.setCapacityBytes(childDataStoreAnswer.getPoolInfo().getCapacityBytes());
dataStoreVO.setUsedBytes(childDataStoreAnswer.getPoolInfo().getCapacityBytes() - childDataStoreAnswer.getPoolInfo().getAvailableBytes());
dataStoreVO.setHypervisor(poolVO.getHypervisor());
dataStoreVO.setScope(poolVO.getScope());
Map<String, String> details = new HashMap<>();
if(StringUtils.isNotEmpty(childDataStoreAnswer.getPoolType())) {
details.put("pool_type", childDataStoreAnswer.getPoolType());
}
List<String> storageTags = storagePoolTagsDao.getStoragePoolTags(poolId);
storageTags.add("DataStoreCluster-" + poolVO.getUuid());
primaryStoreDao.persist(dataStoreVO, details, storageTags);
updateStoragePoolHostVOAndDetails(dataStoreVO, hostId, childDataStoreAnswer);
}
s_logger.info("Connection established between storage pool " + pool + " and host " + hostId);
return true;
}
private void updateStoragePoolHostVOAndDetails(StoragePool pool, long hostId, ModifyStoragePoolAnswer mspAnswer) {
StoragePoolHostVO poolHost = storagePoolHostDao.findByPoolHost(pool.getId(), hostId);
if (poolHost == null) {
poolHost = new StoragePoolHostVO(pool.getId(), hostId, mspAnswer.getPoolInfo().getLocalPath().replaceAll("//", "/"));
@ -101,20 +153,17 @@ public class DefaultHostListener implements HypervisorHostListener {
poolHost.setLocalPath(mspAnswer.getPoolInfo().getLocalPath().replaceAll("//", "/"));
}
StoragePoolVO poolVO = this.primaryStoreDao.findById(poolId);
StoragePoolVO poolVO = this.primaryStoreDao.findById(pool.getId());
poolVO.setUsedBytes(mspAnswer.getPoolInfo().getCapacityBytes() - mspAnswer.getPoolInfo().getAvailableBytes());
poolVO.setCapacityBytes(mspAnswer.getPoolInfo().getCapacityBytes());
if(StringUtils.isNotEmpty(mspAnswer.getPoolType())) {
StoragePoolDetailVO poolType = storagePoolDetailsDao.findDetail(poolId, "pool_type");
StoragePoolDetailVO poolType = storagePoolDetailsDao.findDetail(pool.getId(), "pool_type");
if (poolType == null) {
StoragePoolDetailVO storagePoolDetailVO = new StoragePoolDetailVO(poolId, "pool_type", mspAnswer.getPoolType(), false);
StoragePoolDetailVO storagePoolDetailVO = new StoragePoolDetailVO(pool.getId(), "pool_type", mspAnswer.getPoolType(), false);
storagePoolDetailsDao.persist(storagePoolDetailVO);
}
}
primaryStoreDao.update(pool.getId(), poolVO);
s_logger.info("Connection established between storage pool " + pool + " and host " + hostId);
return true;
}
@Override

View File

@ -177,6 +177,7 @@ import com.cloud.hypervisor.vmware.mo.HostStorageSystemMO;
import com.cloud.hypervisor.vmware.mo.HypervisorHostHelper;
import com.cloud.hypervisor.vmware.mo.NetworkDetails;
import com.cloud.hypervisor.vmware.mo.TaskMO;
import com.cloud.hypervisor.vmware.mo.StoragepodMO;
import com.cloud.hypervisor.vmware.mo.VirtualEthernetCardType;
import com.cloud.hypervisor.vmware.mo.VirtualMachineDiskInfoBuilder;
import com.cloud.hypervisor.vmware.mo.VirtualMachineMO;
@ -4918,11 +4919,43 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
long capacity = 0;
long available = 0;
List<ModifyStoragePoolAnswer> childDatastoresModifyStoragePoolAnswers = new ArrayList<>();
if (pool.getType() == StoragePoolType.DatastoreCluster) {
StoragePodSummary summary = dsMo.getDatastoreClusterSummary();
capacity = summary.getCapacity();
available = summary.getFreeSpace();
StoragepodMO datastoreClusterMo = new StoragepodMO(getServiceContext(), morDatastore);
StoragePodSummary dsClusterSummary = datastoreClusterMo.getDatastoreClusterSummary();
capacity = dsClusterSummary.getCapacity();
available = dsClusterSummary.getFreeSpace();
List<ManagedObjectReference> childDatastoreMors = datastoreClusterMo.getDatastoresInDatastoreCluster();
for (ManagedObjectReference childDsMor : childDatastoreMors) {
DatastoreMO childDsMo = new DatastoreMO(getServiceContext(), childDsMor);
Map<String, TemplateProp> tInfo = new HashMap<>();
DatastoreSummary summary = childDsMo.getDatastoreSummary();;
ModifyStoragePoolAnswer answer = new ModifyStoragePoolAnswer(cmd, summary.getCapacity(), summary.getFreeSpace(), tInfo);
StoragePoolInfo poolInfo = answer.getPoolInfo();
poolInfo.setName(summary.getName());
String datastoreClusterPath = pool.getPath();
int pathstartPosition = datastoreClusterPath.lastIndexOf('/');
String datacenterName = datastoreClusterPath.substring(0, pathstartPosition+1);
String childPath = datacenterName + summary.getName();
poolInfo.setHostPath(childPath);
String uuid = UUID.nameUUIDFromBytes(((pool.getHost() + childPath)).getBytes()).toString();
poolInfo.setUuid(uuid);
poolInfo.setLocalPath(cmd.LOCAL_PATH_PREFIX + File.separator + uuid);
answer.setPoolInfo(poolInfo);
answer.setPoolType(summary.getType());
answer.setLocalDatastoreName(morDatastore.getValue());
childDsMo.setCustomFieldValue(CustomFieldConstants.CLOUD_UUID, uuid);
HypervisorHostHelper.createBaseFolderInDatastore(childDsMo, hyperHost);
childDatastoresModifyStoragePoolAnswers.add(answer);
}
} else {
HypervisorHostHelper.createBaseFolderInDatastore(dsMo, hyperHost);
DatastoreSummary summary = dsMo.getDatastoreSummary();
capacity = summary.getCapacity();
available = summary.getFreeSpace();
@ -4930,6 +4963,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
Map<String, TemplateProp> tInfo = new HashMap<>();
ModifyStoragePoolAnswer answer = new ModifyStoragePoolAnswer(cmd, capacity, available, tInfo);
answer.setDatastoreClusterChildren(childDatastoresModifyStoragePoolAnswers);
if (cmd.getAdd() && (pool.getType() == StoragePoolType.VMFS || pool.getType() == StoragePoolType.PreSetup) && pool.getType() != StoragePoolType.DatastoreCluster) {
answer.setPoolType(dsMo.getDatastoreType());
@ -5312,14 +5346,15 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
ManagedObjectReference morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, cmd.getStorageId());
if (morDs != null) {
DatastoreMO datastoreMo = new DatastoreMO(context, morDs);
long capacity = 0;
long free = 0;
if (cmd.getPooltype() == StoragePoolType.DatastoreCluster) {
StoragePodSummary summary = datastoreMo.getDatastoreClusterSummary();
StoragepodMO datastoreClusterMo = new StoragepodMO(getServiceContext(), morDs);
StoragePodSummary summary = datastoreClusterMo.getDatastoreClusterSummary();
capacity = summary.getCapacity();
free = summary.getFreeSpace();
} else {
DatastoreMO datastoreMo = new DatastoreMO(context, morDs);
DatastoreSummary summary = datastoreMo.getDatastoreSummary();
capacity = summary.getCapacity();
free = summary.getFreeSpace();

View File

@ -33,7 +33,6 @@ import com.vmware.vim25.ObjectSpec;
import com.vmware.vim25.PropertyFilterSpec;
import com.vmware.vim25.PropertySpec;
import com.vmware.vim25.SelectionSpec;
import com.vmware.vim25.StoragePodSummary;
import com.vmware.vim25.TraversalSpec;
import org.apache.log4j.Logger;
@ -68,10 +67,6 @@ public class DatastoreMO extends BaseMO {
return (DatastoreSummary)_context.getVimClient().getDynamicProperty(_mor, "summary");
}
public StoragePodSummary getDatastoreClusterSummary() throws Exception {
return (StoragePodSummary)_context.getVimClient().getDynamicProperty(_mor, "summary");
}
public HostDatastoreBrowserMO getHostDatastoreBrowserMO() throws Exception {
return new HostDatastoreBrowserMO(_context, (ManagedObjectReference)_context.getVimClient().getDynamicProperty(_mor, "browser"));
}

View File

@ -28,7 +28,6 @@ import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import com.cloud.storage.Storage;
import com.google.gson.Gson;
import com.vmware.vim25.AboutInfo;
import com.vmware.vim25.AlreadyExistsFaultMsg;
@ -890,8 +889,8 @@ public class HostMO extends BaseMO implements VmwareHypervisorHost {
}
}
if (dsMo != null) {
HypervisorHostHelper.createBaseFolder(dsMo, this, "StoragePod".equals(morDatastore.getType()) ? Storage.StoragePoolType.DatastoreCluster: null);
if (dsMo != null && !"StoragePod".equals(morDatastore.getType())) {
HypervisorHostHelper.createBaseFolderInDatastore(dsMo, this);
}
if (s_logger.isTraceEnabled())

View File

@ -2088,7 +2088,8 @@ public class HypervisorHostHelper {
public static void createBaseFolder(DatastoreMO dsMo, VmwareHypervisorHost hyperHost, StoragePoolType poolType) throws Exception {
if (poolType != null && poolType == StoragePoolType.DatastoreCluster) {
List<ManagedObjectReference> datastoresInCluster = hyperHost.getContext().getVimClient().getDynamicProperty(dsMo.getMor(), "childEntity");
StoragepodMO storagepodMO = new StoragepodMO(hyperHost.getContext(), dsMo.getMor());
List<ManagedObjectReference> datastoresInCluster = storagepodMO.getDatastoresInDatastoreCluster();
for (ManagedObjectReference datastore : datastoresInCluster) {
DatastoreMO childDsMo = new DatastoreMO(hyperHost.getContext(), datastore);
createBaseFolderInDatastore(childDsMo, hyperHost);
@ -2098,7 +2099,7 @@ public class HypervisorHostHelper {
}
}
private static void createBaseFolderInDatastore(DatastoreMO dsMo, VmwareHypervisorHost hyperHost) throws Exception {
public static void createBaseFolderInDatastore(DatastoreMO dsMo, VmwareHypervisorHost hyperHost) throws Exception {
String dsPath = String.format("[%s]", dsMo.getName());
String folderPath = String.format("[%s] %s", dsMo.getName(), VSPHERE_DATASTORE_BASE_FOLDER);

View File

@ -0,0 +1,48 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package com.cloud.hypervisor.vmware.mo;
import com.cloud.hypervisor.vmware.util.VmwareContext;
import com.vmware.vim25.ManagedObjectReference;
import com.vmware.vim25.StoragePodSummary;
import org.apache.log4j.Logger;
import java.util.List;
public class StoragepodMO extends BaseMO {
private static final Logger LOGGER = Logger.getLogger(StoragepodMO.class);
public StoragepodMO(VmwareContext context, ManagedObjectReference mor) {
super(context, mor);
}
public StoragepodMO(VmwareContext context, String morType, String morValue) {
super(context, morType, morValue);
}
public StoragePodSummary getDatastoreClusterSummary() throws Exception {
return (StoragePodSummary)_context.getVimClient().getDynamicProperty(_mor, "summary");
}
public List<ManagedObjectReference> getDatastoresInDatastoreCluster() throws Exception {
List<ManagedObjectReference> datastoresInCluster = _context.getVimClient().getDynamicProperty(_mor, "childEntity");
return datastoresInCluster;
}
}