mirror of
				https://github.com/apache/cloudstack.git
				synced 2025-10-26 08:42:29 +01:00 
			
		
		
		
	Fix migrate vm and volume APIs in case if datastore cluster
This commit is contained in:
		
							parent
							
								
									fc05d3168f
								
							
						
					
					
						commit
						61dd85876b
					
				| @ -106,4 +106,6 @@ public interface StoragePool extends Identity, InternalIdentity { | |||||||
|     Hypervisor.HypervisorType getHypervisor(); |     Hypervisor.HypervisorType getHypervisor(); | ||||||
| 
 | 
 | ||||||
|     boolean isManaged(); |     boolean isManaged(); | ||||||
|  | 
 | ||||||
|  |     Long getParent(); | ||||||
| } | } | ||||||
|  | |||||||
| @ -100,6 +100,10 @@ public class DiskProfile { | |||||||
|         return name; |         return name; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     public void setTags(String[] tags) { | ||||||
|  |         this.tags = tags; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     /** |     /** | ||||||
|      * @return tags for the disk. This can be used to match it to different storage pools. |      * @return tags for the disk. This can be used to match it to different storage pools. | ||||||
|      */ |      */ | ||||||
|  | |||||||
| @ -84,6 +84,8 @@ public interface VolumeOrchestrationService { | |||||||
| 
 | 
 | ||||||
|     String getVmNameOnVolume(Volume volume); |     String getVmNameOnVolume(Volume volume); | ||||||
| 
 | 
 | ||||||
|  |     StoragePool findChildDataStoreInDataStoreCluster(DataCenter dc, Pod pod, Long clusterId, Long hostId, VirtualMachine vm, Long datastoreClusterId); | ||||||
|  | 
 | ||||||
|     VolumeInfo createVolumeFromSnapshot(Volume volume, Snapshot snapshot, UserVm vm) throws StorageUnavailableException; |     VolumeInfo createVolumeFromSnapshot(Volume volume, Snapshot snapshot, UserVm vm) throws StorageUnavailableException; | ||||||
| 
 | 
 | ||||||
|     Volume migrateVolume(Volume volume, StoragePool destPool) throws StorageUnavailableException; |     Volume migrateVolume(Volume volume, StoragePool destPool) throws StorageUnavailableException; | ||||||
|  | |||||||
| @ -58,4 +58,6 @@ public interface PrimaryDataStoreInfo extends StoragePool { | |||||||
|     Map<String, String> getDetails(); |     Map<String, String> getDetails(); | ||||||
| 
 | 
 | ||||||
|     PrimaryDataStoreLifeCycle getLifeCycle(); |     PrimaryDataStoreLifeCycle getLifeCycle(); | ||||||
|  | 
 | ||||||
|  |     Long getParent(); | ||||||
| } | } | ||||||
|  | |||||||
| @ -51,4 +51,6 @@ public interface StoragePoolAllocator extends Adapter { | |||||||
|     List<StoragePool> allocateToPool(DiskProfile dskCh, VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo); |     List<StoragePool> allocateToPool(DiskProfile dskCh, VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo); | ||||||
| 
 | 
 | ||||||
|     static int RETURN_UPTO_ALL = -1; |     static int RETURN_UPTO_ALL = -1; | ||||||
|  | 
 | ||||||
|  |     List<StoragePool> reorderPools(List<StoragePool> pools, VirtualMachineProfile vmProfile, DeploymentPlan plan); | ||||||
| } | } | ||||||
|  | |||||||
| @ -296,6 +296,34 @@ public class VolumeOrchestrator extends ManagerBase implements VolumeOrchestrati | |||||||
|         return null; |         return null; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     @Override | ||||||
|  |     public StoragePool findChildDataStoreInDataStoreCluster(DataCenter dc, Pod pod, Long clusterId, Long hostId, VirtualMachine vm, Long datastoreClusterId) { | ||||||
|  |         Long podId = null; | ||||||
|  |         if (pod != null) { | ||||||
|  |             podId = pod.getId(); | ||||||
|  |         } else if (clusterId != null) { | ||||||
|  |             Cluster cluster = _entityMgr.findById(Cluster.class, clusterId); | ||||||
|  |             if (cluster != null) { | ||||||
|  |                 podId = cluster.getPodId(); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         List<StoragePoolVO> childDatastores = _storagePoolDao.listChildStoragePoolsInDatastoreCluster(datastoreClusterId); | ||||||
|  |         List<StoragePool> suitablePools = new ArrayList<StoragePool>(); | ||||||
|  | 
 | ||||||
|  |         for (StoragePoolVO childDatastore: childDatastores) | ||||||
|  |             suitablePools.add((StoragePool)dataStoreMgr.getDataStore(childDatastore.getId(), DataStoreRole.Primary)); | ||||||
|  | 
 | ||||||
|  |         VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm); | ||||||
|  |         for (StoragePoolAllocator allocator : _storagePoolAllocators) { | ||||||
|  |             DataCenterDeployment plan = new DataCenterDeployment(dc.getId(), podId, clusterId, hostId, null, null); | ||||||
|  |             final List<StoragePool> poolList = allocator.reorderPools(suitablePools, profile, plan); | ||||||
|  | 
 | ||||||
|  |             if (poolList != null && !poolList.isEmpty()) { | ||||||
|  |                 return (StoragePool)dataStoreMgr.getDataStore(poolList.get(0).getId(), DataStoreRole.Primary); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         return null; | ||||||
|  |     } | ||||||
|     public Pair<Pod, Long> findPod(VirtualMachineTemplate template, ServiceOffering offering, DataCenter dc, long accountId, Set<Long> avoids) { |     public Pair<Pod, Long> findPod(VirtualMachineTemplate template, ServiceOffering offering, DataCenter dc, long accountId, Set<Long> avoids) { | ||||||
|         for (PodAllocator allocator : _podAllocators) { |         for (PodAllocator allocator : _podAllocators) { | ||||||
|             final Pair<Pod, Long> pod = allocator.allocateTo(template, offering, dc, accountId, avoids); |             final Pair<Pod, Long> pod = allocator.allocateTo(template, offering, dc, accountId, avoids); | ||||||
|  | |||||||
| @ -90,7 +90,7 @@ public abstract class AbstractStoragePoolAllocator extends AdapterBase implement | |||||||
|     @Override |     @Override | ||||||
|     public List<StoragePool> allocateToPool(DiskProfile dskCh, VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo) { |     public List<StoragePool> allocateToPool(DiskProfile dskCh, VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo) { | ||||||
|         List<StoragePool> pools = select(dskCh, vmProfile, plan, avoid, returnUpTo); |         List<StoragePool> pools = select(dskCh, vmProfile, plan, avoid, returnUpTo); | ||||||
|         return reOrder(pools, vmProfile, plan); |         return reorderPools(pools, vmProfile, plan); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     protected List<StoragePool> reorderPoolsByCapacity(DeploymentPlan plan, |     protected List<StoragePool> reorderPoolsByCapacity(DeploymentPlan plan, | ||||||
| @ -156,7 +156,8 @@ public abstract class AbstractStoragePoolAllocator extends AdapterBase implement | |||||||
|         return reorderedPools; |         return reorderedPools; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     protected List<StoragePool> reOrder(List<StoragePool> pools, VirtualMachineProfile vmProfile, DeploymentPlan plan) { |     @Override | ||||||
|  |     public List<StoragePool> reorderPools(List<StoragePool> pools, VirtualMachineProfile vmProfile, DeploymentPlan plan) { | ||||||
|         if (pools == null) { |         if (pools == null) { | ||||||
|             return null; |             return null; | ||||||
|         } |         } | ||||||
|  | |||||||
| @ -241,6 +241,11 @@ public class PrimaryDataStoreImpl implements PrimaryDataStore { | |||||||
|         return pdsv.isManaged(); |         return pdsv.isManaged(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     @Override | ||||||
|  |     public Long getParent() { | ||||||
|  |         return pdsv.getParent(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     private boolean canCloneVolume() { |     private boolean canCloneVolume() { | ||||||
|         return Boolean.valueOf(getDriver().getCapabilities().get(DataStoreCapabilities.CAN_CREATE_VOLUME_FROM_VOLUME.toString())); |         return Boolean.valueOf(getDriver().getCapabilities().get(DataStoreCapabilities.CAN_CREATE_VOLUME_FROM_VOLUME.toString())); | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -27,10 +27,13 @@ import java.util.HashMap; | |||||||
| import java.util.Iterator; | import java.util.Iterator; | ||||||
| import java.util.List; | import java.util.List; | ||||||
| import java.util.Map; | import java.util.Map; | ||||||
|  | import java.util.Set; | ||||||
| import java.util.TimeZone; | import java.util.TimeZone; | ||||||
| import java.util.concurrent.Executors; | import java.util.concurrent.Executors; | ||||||
| import java.util.concurrent.ScheduledExecutorService; | import java.util.concurrent.ScheduledExecutorService; | ||||||
| import java.util.concurrent.TimeUnit; | import java.util.concurrent.TimeUnit; | ||||||
|  | import java.util.function.Predicate; | ||||||
|  | import java.util.stream.Collectors; | ||||||
| 
 | 
 | ||||||
| import javax.crypto.Mac; | import javax.crypto.Mac; | ||||||
| import javax.crypto.spec.SecretKeySpec; | import javax.crypto.spec.SecretKeySpec; | ||||||
| @ -1482,10 +1485,26 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe | |||||||
|         } else { |         } else { | ||||||
|             suitablePools = allPools; |             suitablePools = allPools; | ||||||
|         } |         } | ||||||
| 
 |         abstractDataStoreClustersList((List<StoragePool>) allPools); | ||||||
|  |         abstractDataStoreClustersList((List<StoragePool>) suitablePools); | ||||||
|         return new Pair<List<? extends StoragePool>, List<? extends StoragePool>>(allPools, suitablePools); |         return new Pair<List<? extends StoragePool>, List<? extends StoragePool>>(allPools, suitablePools); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     private void abstractDataStoreClustersList(List<StoragePool> storagePools) { | ||||||
|  |         Predicate<StoragePool> childDatastorePredicate = pool -> (pool.getParent() != 0); | ||||||
|  |         List<StoragePool> childDatastores = storagePools.stream().filter(childDatastorePredicate).collect(Collectors.toList()); | ||||||
|  | 
 | ||||||
|  |         if (!childDatastores.isEmpty()) { | ||||||
|  |             storagePools.removeAll(childDatastores); | ||||||
|  |             Set<Long> parentStoragePoolIds = childDatastores.stream().map(mo -> mo.getParent()).collect(Collectors.toSet()); | ||||||
|  |             for (Long parentStoragePoolId : parentStoragePoolIds) { | ||||||
|  |                 StoragePool parentPool = _poolDao.findById(parentStoragePoolId); | ||||||
|  |                 if (!storagePools.contains(parentPool)) | ||||||
|  |                     storagePools.add(parentPool); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     /** |     /** | ||||||
|      * This method looks for all storage pools that are compatible with the given volume. |      * This method looks for all storage pools that are compatible with the given volume. | ||||||
|      * <ul> |      * <ul> | ||||||
|  | |||||||
| @ -30,6 +30,7 @@ import java.util.concurrent.ExecutionException; | |||||||
| 
 | 
 | ||||||
| import javax.inject.Inject; | import javax.inject.Inject; | ||||||
| 
 | 
 | ||||||
|  | import com.cloud.dc.Pod; | ||||||
| import org.apache.cloudstack.api.command.user.volume.AttachVolumeCmd; | import org.apache.cloudstack.api.command.user.volume.AttachVolumeCmd; | ||||||
| import org.apache.cloudstack.api.command.user.volume.CreateVolumeCmd; | import org.apache.cloudstack.api.command.user.volume.CreateVolumeCmd; | ||||||
| import org.apache.cloudstack.api.command.user.volume.DetachVolumeCmd; | import org.apache.cloudstack.api.command.user.volume.DetachVolumeCmd; | ||||||
| @ -2192,6 +2193,13 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic | |||||||
|             throw new InvalidParameterValueException("Cannot migrate volume " + vol + "to the destination storage pool " + destPool.getName() + " as the storage pool is in maintenance mode."); |             throw new InvalidParameterValueException("Cannot migrate volume " + vol + "to the destination storage pool " + destPool.getName() + " as the storage pool is in maintenance mode."); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         if (destPool.getPoolType() == Storage.StoragePoolType.DatastoreCluster) { | ||||||
|  |             DataCenter dc = _entityMgr.findById(DataCenter.class, vol.getDataCenterId()); | ||||||
|  |             Pod destPoolPod = _entityMgr.findById(Pod.class, destPool.getPodId()); | ||||||
|  | 
 | ||||||
|  |             destPool = _volumeMgr.findChildDataStoreInDataStoreCluster(dc, destPoolPod, destPool.getClusterId(), null, null, destPool.getId()); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         if (!storageMgr.storagePoolHasEnoughSpace(Collections.singletonList(vol), destPool)) { |         if (!storageMgr.storagePoolHasEnoughSpace(Collections.singletonList(vol), destPool)) { | ||||||
|             throw new CloudRuntimeException("Storage pool " + destPool.getName() + " does not have enough space to migrate volume " + vol.getName()); |             throw new CloudRuntimeException("Storage pool " + destPool.getName() + " does not have enough space to migrate volume " + vol.getName()); | ||||||
|         } |         } | ||||||
|  | |||||||
| @ -504,6 +504,8 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir | |||||||
|     private ResourceTagDao resourceTagDao; |     private ResourceTagDao resourceTagDao; | ||||||
|     @Inject |     @Inject | ||||||
|     private TemplateOVFPropertiesDao templateOVFPropertiesDao; |     private TemplateOVFPropertiesDao templateOVFPropertiesDao; | ||||||
|  |     @Inject | ||||||
|  |     private VolumeOrchestrationService _volumeMgr; | ||||||
| 
 | 
 | ||||||
|     private ScheduledExecutorService _executor = null; |     private ScheduledExecutorService _executor = null; | ||||||
|     private ScheduledExecutorService _vmIpFetchExecutor = null; |     private ScheduledExecutorService _vmIpFetchExecutor = null; | ||||||
| @ -5556,6 +5558,12 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir | |||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         checkDestinationHypervisorType(destPool, vm); |         checkDestinationHypervisorType(destPool, vm); | ||||||
|  |         if (destPool.getPoolType() == Storage.StoragePoolType.DatastoreCluster) { | ||||||
|  |             DataCenter dc = _entityMgr.findById(DataCenter.class, vm.getDataCenterId()); | ||||||
|  |             Pod destPoolPod = _entityMgr.findById(Pod.class, destPool.getPodId()); | ||||||
|  | 
 | ||||||
|  |             destPool = _volumeMgr.findChildDataStoreInDataStoreCluster(dc, destPoolPod, destPool.getClusterId(), null, null, destPool.getId()); | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|         _itMgr.storageMigration(vm.getUuid(), destPool); |         _itMgr.storageMigration(vm.getUuid(), destPool); | ||||||
|         return _vmDao.findById(vm.getId()); |         return _vmDao.findById(vm.getId()); | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user