mirror of https://github.com/apache/cloudstack.git
DataStore Clusters addition as a storage pool
This commit is contained in:
parent
c45b83a158
commit
48786b2d31
|
|
@ -16,11 +16,11 @@
|
|||
// under the License.
|
||||
package com.cloud.storage;
|
||||
|
||||
import org.apache.commons.lang.NotImplementedException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang.NotImplementedException;
|
||||
|
||||
public class Storage {
|
||||
public static enum ImageFormat {
|
||||
QCOW2(true, true, false, "qcow2"),
|
||||
|
|
@ -135,7 +135,8 @@ public class Storage {
|
|||
OCFS2(true, false),
|
||||
SMB(true, false),
|
||||
Gluster(true, false),
|
||||
ManagedNFS(true, false);
|
||||
ManagedNFS(true, false),
|
||||
DatastoreCluster(true, true); // for VMware, to abstract pool of clusters
|
||||
|
||||
private final boolean shared;
|
||||
private final boolean overprovisioning;
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ public class StorageTest {
|
|||
Assert.assertTrue(StoragePoolType.SMB.isShared());
|
||||
Assert.assertTrue(StoragePoolType.Gluster.isShared());
|
||||
Assert.assertTrue(StoragePoolType.ManagedNFS.isShared());
|
||||
Assert.assertTrue(StoragePoolType.DatastoreCluster.isShared());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -66,5 +67,6 @@ public class StorageTest {
|
|||
Assert.assertFalse(StoragePoolType.SMB.supportsOverProvisioning());
|
||||
Assert.assertFalse(StoragePoolType.Gluster.supportsOverProvisioning());
|
||||
Assert.assertFalse(StoragePoolType.ManagedNFS.supportsOverProvisioning());
|
||||
Assert.assertFalse(StoragePoolType.DatastoreCluster.supportsOverProvisioning());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,20 +18,6 @@
|
|||
*/
|
||||
package org.apache.cloudstack.storage.datastore.provider;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailVO;
|
||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener;
|
||||
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
||||
|
||||
import com.cloud.agent.AgentManager;
|
||||
import com.cloud.agent.api.Answer;
|
||||
import com.cloud.agent.api.ModifyStoragePoolAnswer;
|
||||
|
|
@ -43,6 +29,17 @@ import com.cloud.storage.StoragePool;
|
|||
import com.cloud.storage.StoragePoolHostVO;
|
||||
import com.cloud.storage.dao.StoragePoolHostDao;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener;
|
||||
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailVO;
|
||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.List;
|
||||
|
||||
public class DefaultHostListener implements HypervisorHostListener {
|
||||
private static final Logger s_logger = Logger.getLogger(DefaultHostListener.class);
|
||||
|
|
@ -108,8 +105,11 @@ public class DefaultHostListener implements HypervisorHostListener {
|
|||
poolVO.setUsedBytes(mspAnswer.getPoolInfo().getCapacityBytes() - mspAnswer.getPoolInfo().getAvailableBytes());
|
||||
poolVO.setCapacityBytes(mspAnswer.getPoolInfo().getCapacityBytes());
|
||||
if(StringUtils.isNotEmpty(mspAnswer.getPoolType())) {
|
||||
StoragePoolDetailVO storagePoolDetailVO = new StoragePoolDetailVO(poolId, "pool_type", mspAnswer.getPoolType(), false);
|
||||
storagePoolDetailsDao.persist(storagePoolDetailVO);
|
||||
StoragePoolDetailVO poolType = storagePoolDetailsDao.findDetail(poolId, "pool_type");
|
||||
if (poolType == null) {
|
||||
StoragePoolDetailVO storagePoolDetailVO = new StoragePoolDetailVO(poolId, "pool_type", mspAnswer.getPoolType(), false);
|
||||
storagePoolDetailsDao.persist(storagePoolDetailVO);
|
||||
}
|
||||
}
|
||||
primaryStoreDao.update(pool.getId(), poolVO);
|
||||
|
||||
|
|
|
|||
|
|
@ -16,50 +16,9 @@
|
|||
// under the License.
|
||||
package com.cloud.hypervisor.vmware.resource;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.ConnectException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.nio.channels.SocketChannel;
|
||||
import java.rmi.RemoteException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.TimeZone;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.naming.ConfigurationException;
|
||||
import javax.xml.datatype.XMLGregorianCalendar;
|
||||
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.storage.command.CopyCommand;
|
||||
import org.apache.cloudstack.storage.command.StorageSubSystemCommand;
|
||||
import org.apache.cloudstack.storage.configdrive.ConfigDrive;
|
||||
import org.apache.cloudstack.storage.resource.NfsSecondaryStorageResource;
|
||||
import org.apache.cloudstack.storage.to.PrimaryDataStoreTO;
|
||||
import org.apache.cloudstack.storage.to.TemplateObjectTO;
|
||||
import org.apache.cloudstack.storage.to.VolumeObjectTO;
|
||||
import org.apache.cloudstack.utils.volume.VirtualMachineDiskInfo;
|
||||
import org.apache.cloudstack.vm.UnmanagedInstanceTO;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.lang.math.NumberUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.apache.log4j.NDC;
|
||||
import org.joda.time.Duration;
|
||||
|
||||
import com.cloud.agent.IAgentControl;
|
||||
import com.cloud.agent.api.Answer;
|
||||
|
|
@ -297,6 +256,7 @@ import com.vmware.vim25.PerfMetricIntSeries;
|
|||
import com.vmware.vim25.PerfMetricSeries;
|
||||
import com.vmware.vim25.PerfQuerySpec;
|
||||
import com.vmware.vim25.RuntimeFaultFaultMsg;
|
||||
import com.vmware.vim25.StoragePodSummary;
|
||||
import com.vmware.vim25.ToolsUnavailableFaultMsg;
|
||||
import com.vmware.vim25.VAppOvfSectionInfo;
|
||||
import com.vmware.vim25.VAppOvfSectionSpec;
|
||||
|
|
@ -340,6 +300,46 @@ import com.vmware.vim25.VmConfigSpec;
|
|||
import com.vmware.vim25.VmfsDatastoreInfo;
|
||||
import com.vmware.vim25.VmwareDistributedVirtualSwitchPvlanSpec;
|
||||
import com.vmware.vim25.VmwareDistributedVirtualSwitchVlanIdSpec;
|
||||
import org.apache.cloudstack.storage.command.CopyCommand;
|
||||
import org.apache.cloudstack.storage.command.StorageSubSystemCommand;
|
||||
import org.apache.cloudstack.storage.resource.NfsSecondaryStorageResource;
|
||||
import org.apache.cloudstack.storage.to.PrimaryDataStoreTO;
|
||||
import org.apache.cloudstack.storage.to.VolumeObjectTO;
|
||||
import org.apache.cloudstack.utils.volume.VirtualMachineDiskInfo;
|
||||
import org.apache.cloudstack.vm.UnmanagedInstanceTO;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.lang.math.NumberUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.apache.log4j.NDC;
|
||||
import org.joda.time.Duration;
|
||||
|
||||
import javax.naming.ConfigurationException;
|
||||
import javax.xml.datatype.XMLGregorianCalendar;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.ConnectException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.nio.channels.SocketChannel;
|
||||
import java.rmi.RemoteException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.TimeZone;
|
||||
import java.util.UUID;
|
||||
|
||||
import static com.cloud.utils.HumanReadableJson.getHumanReadableBytesJson;
|
||||
import static com.cloud.utils.NumbersUtil.toHumanReadableSize;
|
||||
|
|
@ -4901,7 +4901,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
|||
VmwareHypervisorHost hyperHost = getHyperHost(getServiceContext());
|
||||
StorageFilerTO pool = cmd.getPool();
|
||||
|
||||
if (pool.getType() != StoragePoolType.NetworkFilesystem && pool.getType() != StoragePoolType.VMFS && pool.getType() != StoragePoolType.PreSetup) {
|
||||
if (pool.getType() != StoragePoolType.NetworkFilesystem && pool.getType() != StoragePoolType.VMFS && pool.getType() != StoragePoolType.PreSetup && pool.getType() != StoragePoolType.DatastoreCluster) {
|
||||
throw new Exception("Unsupported storage pool type " + pool.getType());
|
||||
}
|
||||
|
||||
|
|
@ -4914,16 +4914,24 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
|||
assert (morDatastore != null);
|
||||
|
||||
DatastoreMO dsMo = new DatastoreMO(getServiceContext(), morDatastore);
|
||||
HypervisorHostHelper.createBaseFolderInDatastore(dsMo, hyperHost);
|
||||
HypervisorHostHelper.createBaseFolder(dsMo, hyperHost, pool.getType());
|
||||
|
||||
DatastoreSummary summary = dsMo.getSummary();
|
||||
long capacity = summary.getCapacity();
|
||||
long available = summary.getFreeSpace();
|
||||
long capacity = 0;
|
||||
long available = 0;
|
||||
if (pool.getType() == StoragePoolType.DatastoreCluster) {
|
||||
StoragePodSummary summary = dsMo.getDatastoreClusterSummary();
|
||||
capacity = summary.getCapacity();
|
||||
available = summary.getFreeSpace();
|
||||
} else {
|
||||
DatastoreSummary summary = dsMo.getDatastoreSummary();
|
||||
capacity = summary.getCapacity();
|
||||
available = summary.getFreeSpace();
|
||||
}
|
||||
|
||||
Map<String, TemplateProp> tInfo = new HashMap<>();
|
||||
ModifyStoragePoolAnswer answer = new ModifyStoragePoolAnswer(cmd, capacity, available, tInfo);
|
||||
|
||||
if (cmd.getAdd() && (pool.getType() == StoragePoolType.VMFS || pool.getType() == StoragePoolType.PreSetup)) {
|
||||
if (cmd.getAdd() && (pool.getType() == StoragePoolType.VMFS || pool.getType() == StoragePoolType.PreSetup) && pool.getType() != StoragePoolType.DatastoreCluster) {
|
||||
answer.setPoolType(dsMo.getDatastoreType());
|
||||
answer.setLocalDatastoreName(morDatastore.getValue());
|
||||
}
|
||||
|
|
@ -5305,11 +5313,18 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
|||
|
||||
if (morDs != null) {
|
||||
DatastoreMO datastoreMo = new DatastoreMO(context, morDs);
|
||||
DatastoreSummary summary = datastoreMo.getSummary();
|
||||
assert (summary != null);
|
||||
long capacity = 0;
|
||||
long free = 0;
|
||||
if (cmd.getPooltype() == StoragePoolType.DatastoreCluster) {
|
||||
StoragePodSummary summary = datastoreMo.getDatastoreClusterSummary();
|
||||
capacity = summary.getCapacity();
|
||||
free = summary.getFreeSpace();
|
||||
} else {
|
||||
DatastoreSummary summary = datastoreMo.getDatastoreSummary();
|
||||
capacity = summary.getCapacity();
|
||||
free = summary.getFreeSpace();
|
||||
}
|
||||
|
||||
long capacity = summary.getCapacity();
|
||||
long free = summary.getFreeSpace();
|
||||
long used = capacity - free;
|
||||
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
|
|
@ -5317,7 +5332,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
|||
+ ", capacity: " + toHumanReadableSize(capacity) + ", free: " + toHumanReadableSize(free) + ", used: " + toHumanReadableSize(used));
|
||||
}
|
||||
|
||||
if (summary.getCapacity() <= 0) {
|
||||
if (capacity <= 0) {
|
||||
s_logger.warn("Something is wrong with vSphere NFS datastore, rebooting ESX(ESXi) host should help");
|
||||
}
|
||||
|
||||
|
|
@ -5839,7 +5854,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
|||
dsMo.setCustomFieldValue(CustomFieldConstants.CLOUD_UUID, poolUuid);
|
||||
}
|
||||
|
||||
DatastoreSummary dsSummary = dsMo.getSummary();
|
||||
DatastoreSummary dsSummary = dsMo.getDatastoreSummary();
|
||||
String address = hostMo.getHostName();
|
||||
StoragePoolInfo pInfo = new StoragePoolInfo(poolUuid, address, dsMo.getMor().getValue(), "", StoragePoolType.VMFS, dsSummary.getCapacity(),
|
||||
dsSummary.getFreeSpace());
|
||||
|
|
@ -6555,6 +6570,8 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
|||
|
||||
CustomFieldsManagerMO cfmMo = new CustomFieldsManagerMO(context, context.getServiceContent().getCustomFieldsManager());
|
||||
cfmMo.ensureCustomFieldDef("Datastore", CustomFieldConstants.CLOUD_UUID);
|
||||
cfmMo.ensureCustomFieldDef("StoragePod", CustomFieldConstants.CLOUD_UUID);
|
||||
|
||||
if (_publicTrafficInfo != null && _publicTrafficInfo.getVirtualSwitchType() != VirtualSwitchType.StandardVirtualSwitch
|
||||
|| _guestTrafficInfo != null && _guestTrafficInfo.getVirtualSwitchType() != VirtualSwitchType.StandardVirtualSwitch) {
|
||||
cfmMo.ensureCustomFieldDef("DistributedVirtualPortgroup", CustomFieldConstants.CLOUD_GC_DVP);
|
||||
|
|
|
|||
|
|
@ -2962,7 +2962,7 @@ public class VmwareStorageProcessor implements StorageProcessor {
|
|||
throw new Exception("Unable to create a dummy VM for volume creation");
|
||||
}
|
||||
|
||||
Long volumeSizeToUse = volumeSize < dsMo.getSummary().getFreeSpace() ? volumeSize : dsMo.getSummary().getFreeSpace();
|
||||
Long volumeSizeToUse = volumeSize < dsMo.getDatastoreSummary().getFreeSpace() ? volumeSize : dsMo.getDatastoreSummary().getFreeSpace();
|
||||
|
||||
vmMo.createDisk(vmdkDatastorePath, getMBsFromBytes(volumeSizeToUse), dsMo.getMor(), vmMo.getScsiDeviceControllerKey());
|
||||
vmMo.detachDisk(vmdkDatastorePath, false);
|
||||
|
|
|
|||
|
|
@ -18,32 +18,6 @@
|
|||
*/
|
||||
package org.apache.cloudstack.storage.datastore.lifecycle;
|
||||
|
||||
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;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.HostScope;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreLifeCycle;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreParameters;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
|
||||
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
||||
import org.apache.cloudstack.storage.volume.datastore.PrimaryDataStoreHelper;
|
||||
|
||||
import com.cloud.agent.AgentManager;
|
||||
import com.cloud.agent.api.Answer;
|
||||
import com.cloud.agent.api.CreateStoragePoolCommand;
|
||||
|
|
@ -78,6 +52,29 @@ import com.cloud.vm.dao.DomainRouterDao;
|
|||
import com.cloud.vm.dao.SecondaryStorageVmDao;
|
||||
import com.cloud.vm.dao.UserVmDao;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.HostScope;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreLifeCycle;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreParameters;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
|
||||
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
||||
import org.apache.cloudstack.storage.volume.datastore.PrimaryDataStoreHelper;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
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;
|
||||
import java.util.UUID;
|
||||
|
||||
public class CloudStackPrimaryDataStoreLifeCycleImpl implements PrimaryDataStoreLifeCycle {
|
||||
private static final Logger s_logger = Logger.getLogger(CloudStackPrimaryDataStoreLifeCycleImpl.class);
|
||||
|
|
@ -256,6 +253,11 @@ public class CloudStackPrimaryDataStoreLifeCycleImpl implements PrimaryDataStore
|
|||
parameters.setHost(storageHost);
|
||||
parameters.setPort(0);
|
||||
parameters.setPath(hostPath);
|
||||
} else if (scheme.equalsIgnoreCase("DatastoreCluster")) {
|
||||
parameters.setType(StoragePoolType.DatastoreCluster);
|
||||
parameters.setHost(storageHost);
|
||||
parameters.setPort(0);
|
||||
parameters.setPath(hostPath);
|
||||
} else if (scheme.equalsIgnoreCase("iscsi")) {
|
||||
String[] tokens = hostPath.split("/");
|
||||
int lun = NumbersUtil.parseInt(tokens[tokens.length - 1], -1);
|
||||
|
|
@ -360,7 +362,7 @@ public class CloudStackPrimaryDataStoreLifeCycleImpl implements PrimaryDataStore
|
|||
|
||||
if (pool.getPoolType() != StoragePoolType.NetworkFilesystem && pool.getPoolType() != StoragePoolType.Filesystem &&
|
||||
pool.getPoolType() != StoragePoolType.IscsiLUN && pool.getPoolType() != StoragePoolType.Iscsi && pool.getPoolType() != StoragePoolType.VMFS &&
|
||||
pool.getPoolType() != StoragePoolType.SharedMountPoint && pool.getPoolType() != StoragePoolType.PreSetup && pool.getPoolType() != StoragePoolType.OCFS2 &&
|
||||
pool.getPoolType() != StoragePoolType.SharedMountPoint && pool.getPoolType() != StoragePoolType.PreSetup && pool.getPoolType() != StoragePoolType.DatastoreCluster && pool.getPoolType() != StoragePoolType.OCFS2 &&
|
||||
pool.getPoolType() != StoragePoolType.RBD && pool.getPoolType() != StoragePoolType.CLVM && pool.getPoolType() != StoragePoolType.SMB &&
|
||||
pool.getPoolType() != StoragePoolType.Gluster) {
|
||||
s_logger.warn(" Doesn't support storage pool type " + pool.getPoolType());
|
||||
|
|
|
|||
|
|
@ -16,12 +16,10 @@
|
|||
// under the License.
|
||||
package com.cloud.hypervisor.vmware.mo;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.cloud.exception.CloudException;
|
||||
import com.cloud.hypervisor.vmware.util.VmwareContext;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.vmware.pbm.PbmProfile;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.vmware.vim25.DatastoreHostMount;
|
||||
import com.vmware.vim25.DatastoreSummary;
|
||||
import com.vmware.vim25.FileInfo;
|
||||
|
|
@ -35,11 +33,12 @@ 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;
|
||||
|
||||
import com.cloud.exception.CloudException;
|
||||
import com.cloud.hypervisor.vmware.util.VmwareContext;
|
||||
import com.cloud.utils.Pair;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static com.cloud.utils.NumbersUtil.toHumanReadableSize;
|
||||
|
||||
|
|
@ -65,10 +64,14 @@ public class DatastoreMO extends BaseMO {
|
|||
return _name;
|
||||
}
|
||||
|
||||
public DatastoreSummary getSummary() throws Exception {
|
||||
public DatastoreSummary getDatastoreSummary() throws Exception {
|
||||
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"));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,11 +16,7 @@
|
|||
// under the License.
|
||||
package com.cloud.hypervisor.vmware.mo;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import com.cloud.hypervisor.vmware.util.VmwareContext;
|
||||
import com.vmware.vim25.CustomFieldStringValue;
|
||||
import com.vmware.vim25.DatastoreInfo;
|
||||
import com.vmware.vim25.DynamicProperty;
|
||||
|
|
@ -35,12 +31,18 @@ import com.vmware.vim25.ObjectContent;
|
|||
import com.vmware.vim25.ObjectSpec;
|
||||
import com.vmware.vim25.PropertyFilterSpec;
|
||||
import com.vmware.vim25.PropertySpec;
|
||||
import com.vmware.vim25.RetrieveOptions;
|
||||
import com.vmware.vim25.RetrieveResult;
|
||||
import com.vmware.vim25.SelectionSpec;
|
||||
import com.vmware.vim25.TraversalSpec;
|
||||
import com.vmware.vim25.VmfsDatastoreCreateSpec;
|
||||
import com.vmware.vim25.VmfsDatastoreExpandSpec;
|
||||
import com.vmware.vim25.VmfsDatastoreOption;
|
||||
|
||||
import com.cloud.hypervisor.vmware.util.VmwareContext;
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class HostDatastoreSystemMO extends BaseMO {
|
||||
|
||||
|
|
@ -53,6 +55,14 @@ public class HostDatastoreSystemMO extends BaseMO {
|
|||
}
|
||||
|
||||
public ManagedObjectReference findDatastore(String name) throws Exception {
|
||||
ManagedObjectReference morDatastore = findSpecificDatastore(name);
|
||||
if (morDatastore == null) {
|
||||
morDatastore = findDatastoreCluster(name);
|
||||
}
|
||||
return morDatastore;
|
||||
}
|
||||
|
||||
public ManagedObjectReference findSpecificDatastore(String name) throws Exception {
|
||||
// added Apache CloudStack specific name convention, we will use custom field "cloud.uuid" as datastore name as well
|
||||
CustomFieldsManagerMO cfmMo = new CustomFieldsManagerMO(_context, _context.getServiceContent().getCustomFieldsManager());
|
||||
int key = cfmMo.getCustomFieldKey("Datastore", CustomFieldConstants.CLOUD_UUID);
|
||||
|
|
@ -79,6 +89,33 @@ public class HostDatastoreSystemMO extends BaseMO {
|
|||
return null;
|
||||
}
|
||||
|
||||
public ManagedObjectReference findDatastoreCluster(String name) throws Exception {
|
||||
// added Apache CloudStack specific name convention, we will use custom field "cloud.uuid" as datastore name as well
|
||||
CustomFieldsManagerMO cfmMo = new CustomFieldsManagerMO(_context, _context.getServiceContent().getCustomFieldsManager());
|
||||
int key = cfmMo.getCustomFieldKey("StoragePod", CustomFieldConstants.CLOUD_UUID);
|
||||
assert (key != 0);
|
||||
|
||||
List<ObjectContent> ocs = getDatastoreClusterPropertiesOnHostDatastoreSystem(new String[] {"name", String.format("value[%d]", key)});
|
||||
if (ocs != null) {
|
||||
for (ObjectContent oc : ocs) {
|
||||
if (oc.getPropSet().get(0).getVal().equals(name))
|
||||
return oc.getObj();
|
||||
|
||||
if (oc.getPropSet().size() > 1) {
|
||||
DynamicProperty prop = oc.getPropSet().get(1);
|
||||
if (prop != null && prop.getVal() != null) {
|
||||
if (prop.getVal() instanceof CustomFieldStringValue) {
|
||||
String val = ((CustomFieldStringValue)prop.getVal()).getValue();
|
||||
if (val.equalsIgnoreCase(name))
|
||||
return oc.getObj();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<HostUnresolvedVmfsVolume> queryUnresolvedVmfsVolumes() throws Exception {
|
||||
return _context.getService().queryUnresolvedVmfsVolumes(_mor);
|
||||
}
|
||||
|
|
@ -251,4 +288,90 @@ public class HostDatastoreSystemMO extends BaseMO {
|
|||
|
||||
return _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr);
|
||||
}
|
||||
|
||||
public List<ObjectContent> getDatastoreClusterPropertiesOnHostDatastoreSystem(String[] propertyPaths) throws Exception {
|
||||
ManagedObjectReference retVal = null;
|
||||
// Create Property Spec
|
||||
PropertySpec propertySpec = new PropertySpec();
|
||||
propertySpec.setAll(Boolean.FALSE);
|
||||
propertySpec.setType("StoragePod");
|
||||
propertySpec.getPathSet().addAll(Arrays.asList(propertyPaths));
|
||||
|
||||
// Now create Object Spec
|
||||
ObjectSpec objectSpec = new ObjectSpec();
|
||||
objectSpec.setObj(getContext().getRootFolder());
|
||||
objectSpec.setSkip(Boolean.TRUE);
|
||||
objectSpec.getSelectSet().addAll(
|
||||
Arrays.asList(getStorageTraversalSpec()));
|
||||
|
||||
// Create PropertyFilterSpec using the PropertySpec and ObjectPec
|
||||
// created above.
|
||||
PropertyFilterSpec propertyFilterSpec = new PropertyFilterSpec();
|
||||
propertyFilterSpec.getPropSet().add(propertySpec);
|
||||
propertyFilterSpec.getObjectSet().add(objectSpec);
|
||||
|
||||
List<PropertyFilterSpec> listpfs = new ArrayList<PropertyFilterSpec>();
|
||||
listpfs.add(propertyFilterSpec);
|
||||
return retrievePropertiesAllObjects(listpfs);
|
||||
}
|
||||
|
||||
private SelectionSpec[] getStorageTraversalSpec() {
|
||||
// create a traversal spec that start from root folder
|
||||
|
||||
SelectionSpec ssFolders = new SelectionSpec();
|
||||
ssFolders.setName("visitFolders");
|
||||
|
||||
TraversalSpec datacenterSpec = new TraversalSpec();
|
||||
datacenterSpec.setName("dcTodf");
|
||||
datacenterSpec.setType("Datacenter");
|
||||
datacenterSpec.setPath("datastoreFolder");
|
||||
datacenterSpec.setSkip(Boolean.FALSE);
|
||||
datacenterSpec.getSelectSet().add(ssFolders);
|
||||
|
||||
TraversalSpec visitFolder = new TraversalSpec();
|
||||
visitFolder.setType("Folder");
|
||||
visitFolder.setName("visitFolders");
|
||||
visitFolder.setPath("childEntity");
|
||||
visitFolder.setSkip(Boolean.FALSE);
|
||||
|
||||
List<SelectionSpec> ssSpecList = new ArrayList<SelectionSpec>();
|
||||
ssSpecList.add(datacenterSpec);
|
||||
ssSpecList.add(ssFolders);
|
||||
|
||||
visitFolder.getSelectSet().addAll(ssSpecList);
|
||||
return (new SelectionSpec[]{visitFolder});
|
||||
}
|
||||
|
||||
private List<ObjectContent> retrievePropertiesAllObjects(
|
||||
List<PropertyFilterSpec> listpfs) throws Exception {
|
||||
|
||||
RetrieveOptions propObjectRetrieveOpts = new RetrieveOptions();
|
||||
|
||||
List<ObjectContent> listobjcontent = new ArrayList<ObjectContent>();
|
||||
|
||||
RetrieveResult rslts =
|
||||
getContext().getService().retrievePropertiesEx(getContext().getServiceContent().getPropertyCollector(), listpfs,
|
||||
propObjectRetrieveOpts);
|
||||
if (rslts != null && rslts.getObjects() != null
|
||||
&& !rslts.getObjects().isEmpty()) {
|
||||
listobjcontent.addAll(rslts.getObjects());
|
||||
}
|
||||
String token = null;
|
||||
if (rslts != null && rslts.getToken() != null) {
|
||||
token = rslts.getToken();
|
||||
}
|
||||
while (token != null && !token.isEmpty()) {
|
||||
rslts =
|
||||
getContext().getService().continueRetrievePropertiesEx(getContext().getServiceContent().getPropertyCollector(), token);
|
||||
token = null;
|
||||
if (rslts != null) {
|
||||
token = rslts.getToken();
|
||||
if (rslts.getObjects() != null && !rslts.getObjects().isEmpty()) {
|
||||
listobjcontent.addAll(rslts.getObjects());
|
||||
}
|
||||
}
|
||||
}
|
||||
return listobjcontent;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ 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;
|
||||
|
|
@ -873,12 +874,15 @@ public class HostMO extends BaseMO implements VmwareHypervisorHost {
|
|||
} else {
|
||||
morDatastore = _context.getDatastoreMorByPath(poolPath);
|
||||
if (morDatastore == null) {
|
||||
String msg = "Unable to create VMFS datastore. host: " + poolHostAddress + ", port: " + poolHostPort + ", path: " + poolPath + ", uuid: " + poolUuid;
|
||||
s_logger.error(msg);
|
||||
morDatastore = findDatastore(_context.getDatastoreNameFromPath(poolPath));
|
||||
if (morDatastore == null) {
|
||||
String msg = "Unable to create VMFS datastore. host: " + poolHostAddress + ", port: " + poolHostPort + ", path: " + poolPath + ", uuid: " + poolUuid;
|
||||
s_logger.error(msg);
|
||||
|
||||
if (s_logger.isTraceEnabled())
|
||||
s_logger.trace("vCenter API trace - mountDatastore() done(failed)");
|
||||
throw new Exception(msg);
|
||||
if (s_logger.isTraceEnabled())
|
||||
s_logger.trace("vCenter API trace - mountDatastore() done(failed)");
|
||||
throw new Exception(msg);
|
||||
}
|
||||
}
|
||||
|
||||
dsMo = new DatastoreMO(_context, morDatastore);
|
||||
|
|
@ -887,7 +891,7 @@ public class HostMO extends BaseMO implements VmwareHypervisorHost {
|
|||
}
|
||||
|
||||
if (dsMo != null) {
|
||||
HypervisorHostHelper.createBaseFolderInDatastore(dsMo, this);
|
||||
HypervisorHostHelper.createBaseFolder(dsMo, this, "StoragePod".equals(morDatastore.getType()) ? Storage.StoragePoolType.DatastoreCluster: null);
|
||||
}
|
||||
|
||||
if (s_logger.isTraceEnabled())
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ import com.cloud.hypervisor.vmware.util.VmwareContext;
|
|||
import com.cloud.hypervisor.vmware.util.VmwareHelper;
|
||||
import com.cloud.network.Networks.BroadcastDomainType;
|
||||
import com.cloud.offering.NetworkOffering;
|
||||
import com.cloud.storage.Storage.StoragePoolType;
|
||||
import com.cloud.utils.ActionDelegate;
|
||||
import com.cloud.utils.NumbersUtil;
|
||||
import com.cloud.utils.Pair;
|
||||
|
|
@ -172,7 +173,6 @@ public class HypervisorHostHelper {
|
|||
if (morDs == null)
|
||||
morDs = hyperHost.findDatastore(uuidName);
|
||||
|
||||
DatastoreMO dsMo = new DatastoreMO(hyperHost.getContext(), morDs);
|
||||
return morDs;
|
||||
}
|
||||
|
||||
|
|
@ -2086,7 +2086,19 @@ public class HypervisorHostHelper {
|
|||
return DiskControllerType.getType(controller) == DiskControllerType.ide;
|
||||
}
|
||||
|
||||
public static void createBaseFolderInDatastore(DatastoreMO dsMo, VmwareHypervisorHost hyperHost) throws Exception {
|
||||
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");
|
||||
for (ManagedObjectReference datastore : datastoresInCluster) {
|
||||
DatastoreMO childDsMo = new DatastoreMO(hyperHost.getContext(), datastore);
|
||||
createBaseFolderInDatastore(childDsMo, hyperHost);
|
||||
}
|
||||
} else {
|
||||
createBaseFolderInDatastore(dsMo, hyperHost);
|
||||
}
|
||||
}
|
||||
|
||||
private 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);
|
||||
|
||||
|
|
|
|||
|
|
@ -321,6 +321,24 @@ public class VmwareContext {
|
|||
return dcMo.findDatastore(tokens[1]);
|
||||
}
|
||||
|
||||
// path in format of <datacenter name>/<datastore name>
|
||||
public String getDatastoreNameFromPath(String inventoryPath) throws Exception {
|
||||
assert (inventoryPath != null);
|
||||
|
||||
String[] tokens;
|
||||
if (inventoryPath.startsWith("/"))
|
||||
tokens = inventoryPath.substring(1).split("/");
|
||||
else
|
||||
tokens = inventoryPath.split("/");
|
||||
|
||||
if (tokens == null || tokens.length != 2) {
|
||||
s_logger.error("Invalid datastore inventory path. path: " + inventoryPath);
|
||||
return null;
|
||||
}
|
||||
|
||||
return tokens[1];
|
||||
}
|
||||
|
||||
public void waitForTaskProgressDone(ManagedObjectReference morTask) throws Exception {
|
||||
while (true) {
|
||||
TaskInfo tinfo = (TaskInfo)_vimClient.getDynamicProperty(morTask, "info");
|
||||
|
|
|
|||
Loading…
Reference in New Issue