mirror of https://github.com/apache/cloudstack.git
CLOUDSTACK-724: add basic zone wide storage support, refactor storage allocator, need ui support
This commit is contained in:
parent
3902f505ee
commit
8e360f342d
|
|
@ -105,12 +105,6 @@
|
|||
<!--
|
||||
Storage pool allocators
|
||||
-->
|
||||
<bean id="LocalStoragePoolAllocator" class="com.cloud.storage.allocator.LocalStoragePoolAllocator">
|
||||
<property name="name" value="LocalStorage"/>
|
||||
</bean>
|
||||
<bean id="FirstFitStoragePoolAllocator" class="com.cloud.storage.allocator.FirstFitStoragePoolAllocator">
|
||||
<property name="name" value="Storage"/>
|
||||
</bean>
|
||||
|
||||
<bean id="UserConcentratedAllocator" class="com.cloud.agent.manager.allocator.impl.UserConcentratedAllocator">
|
||||
<property name="name" value="User First"/>
|
||||
|
|
|
|||
|
|
@ -66,10 +66,6 @@ under the License.
|
|||
<!--adapter name="FirstFitRouting" class="com.cloud.agent.manager.allocator.impl.RecreateHostAllocator"/-->
|
||||
<!--adapter name="FirstFit" class="com.cloud.agent.manager.allocator.impl.FirstFitAllocator"/-->
|
||||
</adapters>
|
||||
<adapters key="com.cloud.storage.allocator.StoragePoolAllocator">
|
||||
<adapter name="LocalStorage" class="com.cloud.storage.allocator.LocalStoragePoolAllocator"/>
|
||||
<adapter name="Storage" class="com.cloud.storage.allocator.FirstFitStoragePoolAllocator"/>
|
||||
</adapters>
|
||||
<adapters key="com.cloud.agent.manager.allocator.PodAllocator">
|
||||
<adapter name="User First" class="com.cloud.agent.manager.allocator.impl.UserConcentratedAllocator"/>
|
||||
</adapters>
|
||||
|
|
|
|||
|
|
@ -311,4 +311,8 @@ public class DiskOfferingVO implements DiskOffering {
|
|||
public int getSortKey() {
|
||||
return sortKey;
|
||||
}
|
||||
|
||||
public void setRecreatable(boolean recreatable) {
|
||||
this.recreatable = recreatable;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,14 +14,12 @@
|
|||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package com.cloud.storage.allocator;
|
||||
package org.apache.cloudstack.engine.subsystem.api.storage;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import com.cloud.deploy.DeploymentPlan;
|
||||
import com.cloud.deploy.DeploymentPlanner.ExcludeList;
|
||||
import com.cloud.host.Host;
|
||||
import com.cloud.storage.StoragePool;
|
||||
import com.cloud.utils.component.Adapter;
|
||||
import com.cloud.vm.DiskProfile;
|
||||
|
|
@ -31,12 +29,6 @@ import com.cloud.vm.VirtualMachineProfile;
|
|||
/**
|
||||
*/
|
||||
public interface StoragePoolAllocator extends Adapter {
|
||||
|
||||
//keeping since storageMgr is using this API for some existing functionalities
|
||||
List<StoragePool> allocateToPool(DiskProfile dskCh, VirtualMachineProfile<? extends VirtualMachine> vmProfile, long dcId, long podId, Long clusterId, Long hostId, Set<? extends StoragePool> avoids, int returnUpTo);
|
||||
|
||||
String chooseStorageIp(VirtualMachine vm, Host host, Host storage);
|
||||
|
||||
/**
|
||||
* Determines which storage pools are suitable for the guest virtual machine
|
||||
*
|
||||
|
|
@ -105,6 +105,29 @@
|
|||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-antrun-plugin</artifactId>
|
||||
<version>1.7</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>generate-resource</id>
|
||||
<phase>generate-resources</phase>
|
||||
<goals>
|
||||
<goal>run</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<target>
|
||||
<copy
|
||||
todir="${basedir}/target/test-classes/">
|
||||
<fileset dir="${basedir}/../../../utils/conf/">
|
||||
<include name="db.properties" />
|
||||
</fileset>
|
||||
</copy>
|
||||
</target>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,423 @@
|
|||
package org.apache.cloudstack.storage.allocator;
|
||||
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProviderManager;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.ScopeType;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
|
||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mockito;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import com.cloud.dc.ClusterVO;
|
||||
import com.cloud.dc.DataCenterVO;
|
||||
import com.cloud.dc.HostPodVO;
|
||||
import com.cloud.dc.DataCenter.NetworkType;
|
||||
import com.cloud.dc.dao.ClusterDao;
|
||||
import com.cloud.dc.dao.DataCenterDao;
|
||||
import com.cloud.dc.dao.HostPodDao;
|
||||
import com.cloud.deploy.DataCenterDeployment;
|
||||
import com.cloud.deploy.DeploymentPlan;
|
||||
import com.cloud.deploy.DeploymentPlanner.ExcludeList;
|
||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
import com.cloud.org.Cluster.ClusterType;
|
||||
import com.cloud.org.Managed.ManagedState;
|
||||
import com.cloud.storage.DiskOfferingVO;
|
||||
import com.cloud.storage.StorageManager;
|
||||
import com.cloud.storage.StoragePool;
|
||||
import com.cloud.storage.StoragePoolDetailVO;
|
||||
import com.cloud.storage.StoragePoolStatus;
|
||||
import com.cloud.storage.Volume;
|
||||
import com.cloud.storage.VolumeVO;
|
||||
import com.cloud.storage.Storage.StoragePoolType;
|
||||
import com.cloud.storage.dao.DiskOfferingDao;
|
||||
import com.cloud.storage.dao.StoragePoolDao;
|
||||
import com.cloud.storage.dao.StoragePoolDetailsDao;
|
||||
import com.cloud.storage.dao.VolumeDao;
|
||||
import com.cloud.utils.component.ComponentContext;
|
||||
import com.cloud.vm.DiskProfile;
|
||||
import com.cloud.vm.VirtualMachineProfile;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(locations = "classpath:/storageContext.xml")
|
||||
public class StorageAllocatorTest {
|
||||
@Inject
|
||||
StoragePoolDao storagePoolDao;
|
||||
@Inject
|
||||
StorageManager storageMgr;
|
||||
@Inject
|
||||
DiskOfferingDao diskOfferingDao;
|
||||
@Inject
|
||||
VolumeDao volumeDao;
|
||||
@Inject
|
||||
HostPodDao podDao;
|
||||
@Inject
|
||||
ClusterDao clusterDao;
|
||||
@Inject
|
||||
DataCenterDao dcDao;
|
||||
@Inject
|
||||
StoragePoolDetailsDao poolDetailsDao;
|
||||
@Inject
|
||||
DataStoreProviderManager providerMgr;
|
||||
Long dcId = 1l;
|
||||
Long podId = 1l;
|
||||
Long clusterId = 1l;
|
||||
Long volumeId = null;
|
||||
Long diskOfferingId = null;
|
||||
Long storagePoolId = null;
|
||||
VolumeVO volume = null;
|
||||
DiskOfferingVO diskOffering = null;
|
||||
StoragePoolVO storage = null;
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
ComponentContext.initComponentsLifeCycle();
|
||||
|
||||
}
|
||||
|
||||
protected void createDb() {
|
||||
DataCenterVO dc = new DataCenterVO(UUID.randomUUID().toString(), "test", "8.8.8.8", null, "10.0.0.1", null, "10.0.0.1/24",
|
||||
null, null, NetworkType.Basic, null, null, true, true);
|
||||
dc = dcDao.persist(dc);
|
||||
dcId = dc.getId();
|
||||
|
||||
HostPodVO pod = new HostPodVO(UUID.randomUUID().toString(), dc.getId(), "255.255.255.255", "", 8, "test");
|
||||
pod = podDao.persist(pod);
|
||||
podId = pod.getId();
|
||||
|
||||
ClusterVO cluster = new ClusterVO(dc.getId(), pod.getId(), "devcloud cluster");
|
||||
cluster.setHypervisorType(HypervisorType.XenServer.toString());
|
||||
cluster.setClusterType(ClusterType.CloudManaged);
|
||||
cluster.setManagedState(ManagedState.Managed);
|
||||
cluster = clusterDao.persist(cluster);
|
||||
clusterId = cluster.getId();
|
||||
|
||||
DataStoreProvider provider = providerMgr.getDataStoreProvider("ancient primary data store provider");
|
||||
storage = new StoragePoolVO();
|
||||
storage.setDataCenterId(dcId);
|
||||
storage.setPodId(podId);
|
||||
storage.setPoolType(StoragePoolType.NetworkFilesystem);
|
||||
storage.setClusterId(clusterId);
|
||||
storage.setStatus(StoragePoolStatus.Up);
|
||||
storage.setScope(ScopeType.CLUSTER);
|
||||
storage.setAvailableBytes(1000);
|
||||
storage.setCapacityBytes(20000);
|
||||
storage.setHostAddress(UUID.randomUUID().toString());
|
||||
storage.setPath(UUID.randomUUID().toString());
|
||||
storage.setStorageProviderId(provider.getId());
|
||||
storage = storagePoolDao.persist(storage);
|
||||
storagePoolId = storage.getId();
|
||||
|
||||
storageMgr.createCapacityEntry(storage.getId());
|
||||
|
||||
diskOffering = new DiskOfferingVO();
|
||||
diskOffering.setDiskSize(500);
|
||||
diskOffering.setName("test-disk");
|
||||
diskOffering.setSystemUse(false);
|
||||
diskOffering.setUseLocalStorage(false);
|
||||
diskOffering.setCustomized(false);
|
||||
diskOffering.setRecreatable(false);
|
||||
diskOffering = diskOfferingDao.persist(diskOffering);
|
||||
diskOfferingId = diskOffering.getId();
|
||||
|
||||
volume = new VolumeVO(Volume.Type.ROOT, "volume", dcId, 1, 1, diskOffering.getId(), diskOffering.getDiskSize());
|
||||
volume = volumeDao.persist(volume);
|
||||
volumeId = volume.getId();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Inject
|
||||
List<StoragePoolAllocator> allocators;
|
||||
@Test
|
||||
public void testClusterAllocatorMultiplePools() {
|
||||
Long newStorageId = null;
|
||||
try {
|
||||
createDb();
|
||||
|
||||
DataStoreProvider provider = providerMgr.getDataStoreProvider("ancient primary data store provider");
|
||||
storage = new StoragePoolVO();
|
||||
storage.setDataCenterId(dcId);
|
||||
storage.setPodId(podId);
|
||||
storage.setPoolType(StoragePoolType.NetworkFilesystem);
|
||||
storage.setClusterId(clusterId);
|
||||
storage.setStatus(StoragePoolStatus.Up);
|
||||
storage.setScope(ScopeType.CLUSTER);
|
||||
storage.setAvailableBytes(1000);
|
||||
storage.setCapacityBytes(20000);
|
||||
storage.setHostAddress(UUID.randomUUID().toString());
|
||||
storage.setPath(UUID.randomUUID().toString());
|
||||
storage.setStorageProviderId(provider.getId());
|
||||
StoragePoolVO newStorage = storagePoolDao.persist(storage);
|
||||
newStorageId = newStorage.getId();
|
||||
|
||||
DiskProfile profile = new DiskProfile(volume, diskOffering, HypervisorType.XenServer);
|
||||
VirtualMachineProfile vmProfile = Mockito.mock(VirtualMachineProfile.class);
|
||||
Mockito.when(storageMgr.storagePoolHasEnoughSpace(
|
||||
Mockito.anyListOf(Volume.class), Mockito.any(StoragePool.class))).thenReturn(true);
|
||||
DeploymentPlan plan = new DataCenterDeployment(dcId, podId, clusterId, null, null, null);
|
||||
int foundAcct = 0;
|
||||
for (StoragePoolAllocator allocator : allocators) {
|
||||
List<StoragePool> pools = allocator.allocateToPool(profile, vmProfile, plan, new ExcludeList(), 1);
|
||||
if (!pools.isEmpty()) {
|
||||
Assert.assertEquals(pools.size(), 1);
|
||||
foundAcct++;
|
||||
}
|
||||
}
|
||||
|
||||
if (foundAcct > 1 || foundAcct == 0) {
|
||||
Assert.fail();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
cleanDb();
|
||||
|
||||
if (newStorageId != null) {
|
||||
storagePoolDao.remove(newStorageId);
|
||||
}
|
||||
Assert.fail();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClusterAllocator() {
|
||||
try {
|
||||
createDb();
|
||||
DiskProfile profile = new DiskProfile(volume, diskOffering, HypervisorType.XenServer);
|
||||
VirtualMachineProfile vmProfile = Mockito.mock(VirtualMachineProfile.class);
|
||||
Mockito.when(storageMgr.storagePoolHasEnoughSpace(
|
||||
Mockito.anyListOf(Volume.class), Mockito.any(StoragePool.class))).thenReturn(true);
|
||||
DeploymentPlan plan = new DataCenterDeployment(dcId, podId, clusterId, null, null, null);
|
||||
int foundAcct = 0;
|
||||
for (StoragePoolAllocator allocator : allocators) {
|
||||
List<StoragePool> pools = allocator.allocateToPool(profile, vmProfile, plan, new ExcludeList(), 1);
|
||||
if (!pools.isEmpty()) {
|
||||
Assert.assertEquals(pools.get(0).getId(), storage.getId());
|
||||
foundAcct++;
|
||||
}
|
||||
}
|
||||
|
||||
if (foundAcct > 1 || foundAcct == 0) {
|
||||
Assert.fail();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
cleanDb();
|
||||
Assert.fail();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testClusterAllocatorWithTags() {
|
||||
try {
|
||||
createDb();
|
||||
StoragePoolDetailVO detailVO = new StoragePoolDetailVO(this.storagePoolId, "high", "true");
|
||||
poolDetailsDao.persist(detailVO);
|
||||
DiskOfferingVO diskOff = this.diskOfferingDao.findById(diskOffering.getId());
|
||||
List<String> tags = new ArrayList<String>();
|
||||
tags.add("high");
|
||||
diskOff.setTagsArray(tags);
|
||||
diskOfferingDao.update(diskOff.getId(), diskOff);
|
||||
|
||||
DiskProfile profile = new DiskProfile(volume, diskOff, HypervisorType.XenServer);
|
||||
VirtualMachineProfile vmProfile = Mockito.mock(VirtualMachineProfile.class);
|
||||
Mockito.when(storageMgr.storagePoolHasEnoughSpace(
|
||||
Mockito.anyListOf(Volume.class), Mockito.any(StoragePool.class))).thenReturn(true);
|
||||
DeploymentPlan plan = new DataCenterDeployment(dcId, podId, clusterId, null, null, null);
|
||||
int foundAcct = 0;
|
||||
for (StoragePoolAllocator allocator : allocators) {
|
||||
List<StoragePool> pools = allocator.allocateToPool(profile, vmProfile, plan, new ExcludeList(), 1);
|
||||
if (!pools.isEmpty()) {
|
||||
Assert.assertEquals(pools.get(0).getId(), storage.getId());
|
||||
foundAcct++;
|
||||
}
|
||||
}
|
||||
|
||||
if (foundAcct > 1 || foundAcct == 0) {
|
||||
Assert.fail();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
cleanDb();
|
||||
Assert.fail();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClusterAllocatorWithWrongTag() {
|
||||
try {
|
||||
createDb();
|
||||
StoragePoolDetailVO detailVO = new StoragePoolDetailVO(this.storagePoolId, "high", "true");
|
||||
poolDetailsDao.persist(detailVO);
|
||||
DiskOfferingVO diskOff = this.diskOfferingDao.findById(diskOffering.getId());
|
||||
List<String> tags = new ArrayList<String>();
|
||||
tags.add("low");
|
||||
diskOff.setTagsArray(tags);
|
||||
diskOfferingDao.update(diskOff.getId(), diskOff);
|
||||
|
||||
DiskProfile profile = new DiskProfile(volume, diskOff, HypervisorType.XenServer);
|
||||
VirtualMachineProfile vmProfile = Mockito.mock(VirtualMachineProfile.class);
|
||||
Mockito.when(storageMgr.storagePoolHasEnoughSpace(
|
||||
Mockito.anyListOf(Volume.class), Mockito.any(StoragePool.class))).thenReturn(true);
|
||||
DeploymentPlan plan = new DataCenterDeployment(dcId, podId, clusterId, null, null, null);
|
||||
int foundAcct = 0;
|
||||
for (StoragePoolAllocator allocator : allocators) {
|
||||
List<StoragePool> pools = allocator.allocateToPool(profile, vmProfile, plan, new ExcludeList(), 1);
|
||||
if (!pools.isEmpty()) {
|
||||
foundAcct++;
|
||||
}
|
||||
}
|
||||
|
||||
if (foundAcct != 0) {
|
||||
Assert.fail();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
cleanDb();
|
||||
Assert.fail();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testZoneWideStorageAllocator() {
|
||||
try {
|
||||
createDb();
|
||||
|
||||
StoragePoolVO pool = storagePoolDao.findById(storagePoolId);
|
||||
pool.setScope(ScopeType.ZONE);
|
||||
storagePoolDao.update(pool.getId(), pool);
|
||||
|
||||
DiskProfile profile = new DiskProfile(volume, diskOffering, HypervisorType.KVM);
|
||||
VirtualMachineProfile vmProfile = Mockito.mock(VirtualMachineProfile.class);
|
||||
Mockito.when(vmProfile.getHypervisorType()).thenReturn(HypervisorType.KVM);
|
||||
Mockito.when(storageMgr.storagePoolHasEnoughSpace(
|
||||
Mockito.anyListOf(Volume.class), Mockito.any(StoragePool.class))).thenReturn(true);
|
||||
DeploymentPlan plan = new DataCenterDeployment(dcId, podId, clusterId, null, null, null);
|
||||
int foundAcct = 0;
|
||||
for (StoragePoolAllocator allocator : allocators) {
|
||||
List<StoragePool> pools = allocator.allocateToPool(profile, vmProfile, plan, new ExcludeList(), 1);
|
||||
if (!pools.isEmpty()) {
|
||||
Assert.assertEquals(pools.get(0).getId(), storage.getId());
|
||||
foundAcct++;
|
||||
}
|
||||
}
|
||||
|
||||
if (foundAcct > 1 || foundAcct == 0) {
|
||||
Assert.fail();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
cleanDb();
|
||||
Assert.fail();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPoolStateIsNotUp() {
|
||||
try {
|
||||
createDb();
|
||||
|
||||
StoragePoolVO pool = storagePoolDao.findById(storagePoolId);
|
||||
pool.setScope(ScopeType.ZONE);
|
||||
pool.setStatus(StoragePoolStatus.Maintenance);
|
||||
storagePoolDao.update(pool.getId(), pool);
|
||||
|
||||
DiskProfile profile = new DiskProfile(volume, diskOffering, HypervisorType.XenServer);
|
||||
VirtualMachineProfile vmProfile = Mockito.mock(VirtualMachineProfile.class);
|
||||
Mockito.when(storageMgr.storagePoolHasEnoughSpace(
|
||||
Mockito.anyListOf(Volume.class), Mockito.any(StoragePool.class))).thenReturn(true);
|
||||
DeploymentPlan plan = new DataCenterDeployment(dcId, podId, clusterId, null, null, null);
|
||||
int foundAcct = 0;
|
||||
for (StoragePoolAllocator allocator : allocators) {
|
||||
List<StoragePool> pools = allocator.allocateToPool(profile, vmProfile, plan, new ExcludeList(), 1);
|
||||
if (!pools.isEmpty()) {
|
||||
Assert.assertEquals(pools.get(0).getId(), storage.getId());
|
||||
foundAcct++;
|
||||
}
|
||||
}
|
||||
|
||||
if (foundAcct == 1) {
|
||||
Assert.fail();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
cleanDb();
|
||||
Assert.fail();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void testLocalStorageAllocator() {
|
||||
try {
|
||||
createDb();
|
||||
|
||||
StoragePoolVO pool = storagePoolDao.findById(storagePoolId);
|
||||
pool.setScope(ScopeType.HOST);
|
||||
storagePoolDao.update(pool.getId(), pool);
|
||||
|
||||
DiskOfferingVO diskOff = diskOfferingDao.findById(diskOfferingId);
|
||||
diskOff.setUseLocalStorage(true);
|
||||
diskOfferingDao.update(diskOfferingId, diskOff);
|
||||
|
||||
DiskProfile profile = new DiskProfile(volume, diskOff, HypervisorType.XenServer);
|
||||
VirtualMachineProfile vmProfile = Mockito.mock(VirtualMachineProfile.class);
|
||||
Mockito.when(storageMgr.storagePoolHasEnoughSpace(
|
||||
Mockito.anyListOf(Volume.class), Mockito.any(StoragePool.class))).thenReturn(true);
|
||||
DeploymentPlan plan = new DataCenterDeployment(dcId, podId, clusterId, null, null, null);
|
||||
int foundAcct = 0;
|
||||
for (StoragePoolAllocator allocator : allocators) {
|
||||
List<StoragePool> pools = allocator.allocateToPool(profile, vmProfile, plan, new ExcludeList(), 1);
|
||||
if (!pools.isEmpty()) {
|
||||
Assert.assertEquals(pools.get(0).getId(), storage.getId());
|
||||
foundAcct++;
|
||||
}
|
||||
}
|
||||
|
||||
if (foundAcct > 1 || foundAcct == 0) {
|
||||
Assert.fail();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
cleanDb();
|
||||
Assert.fail();
|
||||
}
|
||||
}
|
||||
|
||||
protected void cleanDb() {
|
||||
if (volumeId != null) {
|
||||
volumeDao.remove(volumeId);
|
||||
volumeId = null;
|
||||
}
|
||||
if (diskOfferingId != null) {
|
||||
diskOfferingDao.remove(diskOfferingId);
|
||||
diskOfferingId = null;
|
||||
}
|
||||
if (storagePoolId != null) {
|
||||
storagePoolDao.remove(storagePoolId);
|
||||
storagePoolId = null;
|
||||
}
|
||||
if (clusterId != null) {
|
||||
clusterDao.remove(clusterId);
|
||||
clusterId = null;
|
||||
}
|
||||
if (podId != null) {
|
||||
podDao.remove(podId);
|
||||
podId = null;
|
||||
}
|
||||
if (dcId != null) {
|
||||
dcDao.remove(dcId);
|
||||
dcId = null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
package org.apache.cloudstack.storage.allocator;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.cloudstack.storage.allocator.StorageAllocatorTestConfiguration.Library;
|
||||
import org.mockito.Mockito;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.ComponentScan.Filter;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.FilterType;
|
||||
import org.springframework.core.type.classreading.MetadataReader;
|
||||
import org.springframework.core.type.classreading.MetadataReaderFactory;
|
||||
import org.springframework.core.type.filter.TypeFilter;
|
||||
|
||||
import com.cloud.cluster.agentlb.dao.HostTransferMapDaoImpl;
|
||||
import com.cloud.configuration.dao.ConfigurationDaoImpl;
|
||||
import com.cloud.dc.dao.ClusterDaoImpl;
|
||||
import com.cloud.dc.dao.DataCenterDaoImpl;
|
||||
import com.cloud.domain.dao.DomainDaoImpl;
|
||||
import com.cloud.host.dao.HostDaoImpl;
|
||||
import com.cloud.host.dao.HostDetailsDaoImpl;
|
||||
import com.cloud.host.dao.HostTagsDaoImpl;
|
||||
import com.cloud.storage.StorageManager;
|
||||
import com.cloud.storage.dao.StoragePoolDaoImpl;
|
||||
import com.cloud.storage.dao.StoragePoolDetailsDaoImpl;
|
||||
import com.cloud.storage.dao.VMTemplateDaoImpl;
|
||||
import com.cloud.utils.component.SpringComponentScanUtils;
|
||||
import com.cloud.vm.UserVmManager;
|
||||
|
||||
|
||||
@Configuration
|
||||
@ComponentScan(basePackageClasses={
|
||||
StoragePoolDetailsDaoImpl.class,
|
||||
StoragePoolDaoImpl.class,
|
||||
VMTemplateDaoImpl.class,
|
||||
HostDaoImpl.class,
|
||||
DomainDaoImpl.class,
|
||||
DataCenterDaoImpl.class,
|
||||
},
|
||||
includeFilters={@Filter(value=Library.class, type=FilterType.CUSTOM)},
|
||||
useDefaultFilters=false
|
||||
)
|
||||
public class StorageAllocatorTestConfiguration {
|
||||
@Bean
|
||||
public UserVmManager UserVmManager() {
|
||||
return Mockito.mock(UserVmManager.class);
|
||||
}
|
||||
@Bean
|
||||
public StorageManager StorageManager() {
|
||||
return Mockito.mock(StorageManager.class);
|
||||
}
|
||||
|
||||
public static class Library implements TypeFilter {
|
||||
|
||||
@Override
|
||||
public boolean match(MetadataReader mdr, MetadataReaderFactory arg1) throws IOException {
|
||||
mdr.getClassMetadata().getClassName();
|
||||
ComponentScan cs = StorageAllocatorTestConfiguration.class.getAnnotation(ComponentScan.class);
|
||||
return SpringComponentScanUtils.includedInBasePackageClasses(mdr.getClassMetadata().getClassName(), cs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -20,6 +20,7 @@ import java.io.IOException;
|
|||
|
||||
import org.apache.cloudstack.acl.APIChecker;
|
||||
import org.apache.cloudstack.engine.service.api.OrchestrationService;
|
||||
import org.apache.cloudstack.framework.rpc.RpcProvider;
|
||||
import org.apache.cloudstack.storage.HostEndpointRpcServer;
|
||||
import org.apache.cloudstack.storage.endpoint.EndPointSelector;
|
||||
import org.apache.cloudstack.storage.test.ChildTestConfiguration.Library;
|
||||
|
|
@ -35,46 +36,55 @@ import org.springframework.core.type.filter.TypeFilter;
|
|||
|
||||
import com.cloud.agent.AgentManager;
|
||||
import com.cloud.alert.AlertManager;
|
||||
import com.cloud.capacity.dao.CapacityDaoImpl;
|
||||
import com.cloud.cluster.ClusteredAgentRebalanceService;
|
||||
import com.cloud.cluster.agentlb.dao.HostTransferMapDao;
|
||||
import com.cloud.cluster.agentlb.dao.HostTransferMapDaoImpl;
|
||||
import com.cloud.configuration.dao.ConfigurationDao;
|
||||
import com.cloud.configuration.dao.ConfigurationDaoImpl;
|
||||
import com.cloud.dc.dao.ClusterDao;
|
||||
import com.cloud.dc.ClusterDetailsDaoImpl;
|
||||
import com.cloud.dc.dao.ClusterDaoImpl;
|
||||
import com.cloud.dc.dao.DataCenterDao;
|
||||
import com.cloud.dc.dao.DataCenterDaoImpl;
|
||||
import com.cloud.dc.dao.DataCenterIpAddressDaoImpl;
|
||||
import com.cloud.dc.dao.DataCenterLinkLocalIpAddressDaoImpl;
|
||||
import com.cloud.dc.dao.DataCenterVnetDaoImpl;
|
||||
import com.cloud.dc.dao.DcDetailsDaoImpl;
|
||||
import com.cloud.dc.dao.HostPodDao;
|
||||
import com.cloud.dc.dao.HostPodDaoImpl;
|
||||
import com.cloud.dc.dao.PodVlanDaoImpl;
|
||||
import com.cloud.domain.dao.DomainDao;
|
||||
import com.cloud.domain.dao.DomainDaoImpl;
|
||||
import com.cloud.host.dao.HostDao;
|
||||
import com.cloud.host.dao.HostDetailsDao;
|
||||
import com.cloud.host.dao.HostDaoImpl;
|
||||
import com.cloud.host.dao.HostDetailsDaoImpl;
|
||||
import com.cloud.host.dao.HostTagsDao;
|
||||
import com.cloud.host.dao.HostTagsDaoImpl;
|
||||
import com.cloud.resource.ResourceManager;
|
||||
import com.cloud.server.ManagementServer;
|
||||
import com.cloud.server.auth.UserAuthenticator;
|
||||
import com.cloud.storage.dao.StoragePoolHostDao;
|
||||
import com.cloud.service.dao.ServiceOfferingDaoImpl;
|
||||
import com.cloud.storage.OCFS2ManagerImpl;
|
||||
import com.cloud.storage.StorageManager;
|
||||
import com.cloud.storage.VolumeManager;
|
||||
import com.cloud.storage.dao.DiskOfferingDaoImpl;
|
||||
import com.cloud.storage.dao.SnapshotDaoImpl;
|
||||
import com.cloud.storage.dao.StoragePoolHostDaoImpl;
|
||||
import com.cloud.storage.dao.StoragePoolWorkDaoImpl;
|
||||
import com.cloud.storage.dao.VMTemplateDaoImpl;
|
||||
import com.cloud.storage.dao.VMTemplateDetailsDao;
|
||||
import com.cloud.storage.dao.VMTemplateDetailsDaoImpl;
|
||||
import com.cloud.storage.dao.VMTemplateHostDaoImpl;
|
||||
import com.cloud.storage.dao.VMTemplatePoolDaoImpl;
|
||||
import com.cloud.storage.dao.VMTemplateZoneDao;
|
||||
import com.cloud.storage.dao.VMTemplateZoneDaoImpl;
|
||||
import com.cloud.storage.dao.VolumeDaoImpl;
|
||||
import com.cloud.storage.dao.VolumeHostDaoImpl;
|
||||
import com.cloud.storage.s3.S3Manager;
|
||||
import com.cloud.storage.snapshot.SnapshotManager;
|
||||
import com.cloud.storage.swift.SwiftManager;
|
||||
import com.cloud.tags.dao.ResourceTagsDaoImpl;
|
||||
import com.cloud.template.TemplateManager;
|
||||
import com.cloud.user.dao.UserDaoImpl;
|
||||
import com.cloud.utils.component.SpringComponentScanUtils;
|
||||
import com.cloud.vm.VirtualMachineManager;
|
||||
import com.cloud.vm.dao.ConsoleProxyDaoImpl;
|
||||
import com.cloud.vm.dao.DomainRouterDao;
|
||||
import com.cloud.vm.dao.NicDaoImpl;
|
||||
import com.cloud.vm.dao.SecondaryStorageVmDaoImpl;
|
||||
import com.cloud.vm.dao.UserVmDaoImpl;
|
||||
import com.cloud.vm.dao.UserVmDetailsDaoImpl;
|
||||
import com.cloud.vm.dao.VMInstanceDaoImpl;
|
||||
import com.cloud.vm.snapshot.dao.VMSnapshotDaoImpl;
|
||||
@Configuration
|
||||
@ComponentScan(basePackageClasses={
|
||||
NicDaoImpl.class,
|
||||
|
|
@ -85,88 +95,62 @@ import com.cloud.vm.dao.VMInstanceDaoImpl;
|
|||
VMTemplatePoolDaoImpl.class,
|
||||
ResourceTagsDaoImpl.class,
|
||||
VMTemplateDaoImpl.class,
|
||||
MockStorageMotionStrategy.class
|
||||
MockStorageMotionStrategy.class,
|
||||
ConfigurationDaoImpl.class,
|
||||
ClusterDaoImpl.class,
|
||||
HostPodDaoImpl.class,
|
||||
VMTemplateZoneDaoImpl.class,
|
||||
VMTemplateDetailsDaoImpl.class,
|
||||
HostDaoImpl.class,
|
||||
HostDetailsDaoImpl.class,
|
||||
HostTagsDaoImpl.class,
|
||||
HostTransferMapDaoImpl.class,
|
||||
DataCenterIpAddressDaoImpl.class,
|
||||
DataCenterLinkLocalIpAddressDaoImpl.class,
|
||||
DataCenterVnetDaoImpl.class,
|
||||
PodVlanDaoImpl.class,
|
||||
DcDetailsDaoImpl.class,
|
||||
DiskOfferingDaoImpl.class,
|
||||
StoragePoolHostDaoImpl.class,
|
||||
UserVmDaoImpl.class,
|
||||
UserVmDetailsDaoImpl.class,
|
||||
ServiceOfferingDaoImpl.class,
|
||||
CapacityDaoImpl.class,
|
||||
SnapshotDaoImpl.class,
|
||||
VMSnapshotDaoImpl.class,
|
||||
OCFS2ManagerImpl.class,
|
||||
ClusterDetailsDaoImpl.class,
|
||||
SecondaryStorageVmDaoImpl.class,
|
||||
|
||||
ConsoleProxyDaoImpl.class,
|
||||
StoragePoolWorkDaoImpl.class,
|
||||
UserDaoImpl.class
|
||||
|
||||
},
|
||||
includeFilters={@Filter(value=Library.class, type=FilterType.CUSTOM)},
|
||||
useDefaultFilters=false
|
||||
)
|
||||
public class ChildTestConfiguration extends TestConfiguration {
|
||||
|
||||
@Override
|
||||
@Bean
|
||||
public HostDao hostDao() {
|
||||
HostDao dao = super.hostDao();
|
||||
HostDao nDao = Mockito.spy(dao);
|
||||
return nDao;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public EndPointSelector selector() {
|
||||
return Mockito.mock(EndPointSelector.class);
|
||||
}
|
||||
@Bean
|
||||
public DataCenterDao dcDao() {
|
||||
return new DataCenterDaoImpl();
|
||||
}
|
||||
@Bean
|
||||
public HostDetailsDao hostDetailsDao() {
|
||||
return new HostDetailsDaoImpl();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public HostTagsDao hostTagsDao() {
|
||||
return new HostTagsDaoImpl();
|
||||
}
|
||||
|
||||
@Bean ClusterDao clusterDao() {
|
||||
return new ClusterDaoImpl();
|
||||
}
|
||||
|
||||
@Bean HostTransferMapDao hostTransferDao() {
|
||||
return new HostTransferMapDaoImpl();
|
||||
}
|
||||
@Bean DataCenterIpAddressDaoImpl dataCenterIpAddressDaoImpl() {
|
||||
return new DataCenterIpAddressDaoImpl();
|
||||
}
|
||||
@Bean DataCenterLinkLocalIpAddressDaoImpl dataCenterLinkLocalIpAddressDaoImpl() {
|
||||
return new DataCenterLinkLocalIpAddressDaoImpl();
|
||||
}
|
||||
@Bean DataCenterVnetDaoImpl dataCenterVnetDaoImpl() {
|
||||
return new DataCenterVnetDaoImpl();
|
||||
}
|
||||
@Bean PodVlanDaoImpl podVlanDaoImpl() {
|
||||
return new PodVlanDaoImpl();
|
||||
}
|
||||
@Bean DcDetailsDaoImpl dcDetailsDaoImpl() {
|
||||
return new DcDetailsDaoImpl();
|
||||
}
|
||||
@Bean HostPodDao hostPodDao() {
|
||||
return new HostPodDaoImpl();
|
||||
}
|
||||
@Bean StoragePoolHostDao storagePoolHostDao() {
|
||||
return new StoragePoolHostDaoImpl();
|
||||
}
|
||||
@Bean VMTemplateZoneDao templateZoneDao() {
|
||||
return new VMTemplateZoneDaoImpl();
|
||||
}
|
||||
@Bean VMTemplateDetailsDao templateDetailsDao() {
|
||||
return new VMTemplateDetailsDaoImpl();
|
||||
}
|
||||
@Bean ConfigurationDao configDao() {
|
||||
return new ConfigurationDaoImpl();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public AgentManager agentMgr() {
|
||||
return new DirectAgentManagerSimpleImpl();
|
||||
}
|
||||
@Bean DomainDao domainDao() {
|
||||
return new DomainDaoImpl();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public HostEndpointRpcServer rpcServer() {
|
||||
return new MockHostEndpointRpcServerDirectCallResource();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RpcProvider rpcProvider() {
|
||||
return Mockito.mock(RpcProvider.class);
|
||||
}
|
||||
@Bean
|
||||
public ClusteredAgentRebalanceService _rebalanceService() {
|
||||
return Mockito.mock(ClusteredAgentRebalanceService.class);
|
||||
|
|
@ -183,12 +167,50 @@ public class ChildTestConfiguration extends TestConfiguration {
|
|||
public APIChecker apiChecker() {
|
||||
return Mockito.mock(APIChecker.class);
|
||||
}
|
||||
@Bean
|
||||
public TemplateManager templateMgr() {
|
||||
return Mockito.mock(TemplateManager.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public VolumeManager volumeMgr() {
|
||||
return Mockito.mock(VolumeManager.class);
|
||||
}
|
||||
@Bean
|
||||
public SwiftManager switfMgr() {
|
||||
return Mockito.mock(SwiftManager.class);
|
||||
}
|
||||
@Bean
|
||||
public ManagementServer server() {
|
||||
return Mockito.mock(ManagementServer.class);
|
||||
}
|
||||
@Bean
|
||||
public VirtualMachineManager vmMgr() {
|
||||
return Mockito.mock(VirtualMachineManager.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public S3Manager s3Mgr() {
|
||||
return Mockito.mock(S3Manager.class);
|
||||
}
|
||||
@Bean
|
||||
public SnapshotManager snapshotMgr() {
|
||||
return Mockito.mock(SnapshotManager.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ResourceManager resourceMgr() {
|
||||
return Mockito.mock(ResourceManager.class);
|
||||
}
|
||||
@Bean
|
||||
public DomainRouterDao domainRouterDao() {
|
||||
return Mockito.mock(DomainRouterDao.class);
|
||||
}
|
||||
@Bean
|
||||
public StorageManager storageMgr() {
|
||||
return Mockito.mock(StorageManager.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public AlertManager alertMgr() {
|
||||
return Mockito.mock(AlertManager.class);
|
||||
|
|
@ -204,9 +226,5 @@ public class ChildTestConfiguration extends TestConfiguration {
|
|||
}
|
||||
|
||||
}
|
||||
/* @Override
|
||||
@Bean
|
||||
public PrimaryDataStoreDao primaryDataStoreDao() {
|
||||
return Mockito.mock(PrimaryDataStoreDaoImpl.class);
|
||||
}*/
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,16 +16,8 @@
|
|||
// under the License.
|
||||
package org.apache.cloudstack.storage.test;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import com.cloud.host.dao.HostDao;
|
||||
import com.cloud.host.dao.HostDaoImpl;
|
||||
|
||||
@Configuration
|
||||
public class TestConfiguration {
|
||||
@Bean
|
||||
public HostDao hostDao() {
|
||||
return new HostDaoImpl();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- 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. -->
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
|
||||
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
|
||||
http://www.springframework.org/schema/tx
|
||||
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
|
||||
http://www.springframework.org/schema/aop
|
||||
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
|
||||
http://www.springframework.org/schema/context
|
||||
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
|
||||
|
||||
<context:annotation-config />
|
||||
<context:component-scan base-package="org.apache.cloudstack.storage" />
|
||||
|
||||
|
||||
<!-- @DB support -->
|
||||
<aop:config proxy-target-class="true">
|
||||
<aop:aspect id="dbContextBuilder" ref="transactionContextBuilder">
|
||||
<aop:pointcut id="captureAnyMethod" expression="execution(* *(..))" />
|
||||
|
||||
<aop:around pointcut-ref="captureAnyMethod" method="AroundAnyMethod" />
|
||||
</aop:aspect>
|
||||
|
||||
</aop:config>
|
||||
|
||||
<bean id="transactionContextBuilder" class="com.cloud.utils.db.TransactionContextBuilder" />
|
||||
<bean id="componentContext" class="com.cloud.utils.component.ComponentContext"/>
|
||||
<bean class="org.apache.cloudstack.storage.test.ChildTestConfiguration" />
|
||||
|
||||
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor">
|
||||
<property name="requiredParameterValue" value="false" />
|
||||
</bean>
|
||||
</beans>
|
||||
|
|
@ -23,10 +23,8 @@
|
|||
<context:annotation-config />
|
||||
<context:component-scan
|
||||
base-package="org.apache.cloudstack.storage" />
|
||||
<context:component-scan base-package="com.cloud.utils.db" />
|
||||
<context:component-scan base-package="com.cloud.utils.component" />
|
||||
|
||||
|
||||
<!-- @DB support -->
|
||||
<aop:config proxy-target-class="true">
|
||||
<aop:aspect id="dbContextBuilder" ref="transactionContextBuilder">
|
||||
<aop:pointcut id="captureAnyMethod" expression="execution(* *(..))" />
|
||||
|
|
@ -34,50 +32,12 @@
|
|||
<aop:around pointcut-ref="captureAnyMethod" method="AroundAnyMethod" />
|
||||
</aop:aspect>
|
||||
|
||||
<aop:aspect id="actionEventInterceptorAspect" ref="actionEventInterceptor">
|
||||
<aop:pointcut id="captureEventMethod"
|
||||
expression="execution(* *(..)) and @annotation(com.cloud.event.ActionEvent)" />
|
||||
<aop:around pointcut-ref="captureEventMethod" method="AroundAnyMethod" />
|
||||
</aop:aspect>
|
||||
|
||||
</aop:config>
|
||||
|
||||
|
||||
<bean id="transactionContextBuilder" class="com.cloud.utils.db.TransactionContextBuilder" />
|
||||
<bean id="actionEventInterceptor" class="com.cloud.event.ActionEventInterceptor" />
|
||||
|
||||
<bean id="componentContext" class="com.cloud.utils.component.ComponentContext"/>
|
||||
|
||||
<bean class="org.apache.cloudstack.storage.test.ChildTestConfiguration" />
|
||||
|
||||
<bean id="onwireRegistry"
|
||||
class="org.apache.cloudstack.framework.serializer.OnwireClassRegistry"
|
||||
init-method="scan">
|
||||
<property name="packages">
|
||||
<list>
|
||||
<value>org.apache.cloudstack.framework</value>
|
||||
</list>
|
||||
</property>
|
||||
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor">
|
||||
<property name="requiredParameterValue" value="false" />
|
||||
</bean>
|
||||
|
||||
<bean id="messageSerializer"
|
||||
class="org.apache.cloudstack.framework.serializer.JsonMessageSerializer">
|
||||
<property name="onwireClassRegistry" ref="onwireRegistry" />
|
||||
</bean>
|
||||
|
||||
<bean id="transportProvider"
|
||||
class="org.apache.cloudstack.framework.server.ServerTransportProvider"
|
||||
init-method="initialize">
|
||||
<property name="workerPoolSize" value="5" />
|
||||
<property name="nodeId" value="Node1" />
|
||||
<property name="messageSerializer" ref="messageSerializer" />
|
||||
</bean>
|
||||
|
||||
<bean id="rpcProvider" class="org.apache.cloudstack.framework.rpc.RpcProviderImpl"
|
||||
init-method="initialize">
|
||||
<constructor-arg ref="transportProvider" />
|
||||
<property name="messageSerializer" ref="messageSerializer" />
|
||||
</bean>
|
||||
|
||||
<bean id="eventBus" class="org.apache.cloudstack.framework.eventbus.EventBusBase" />
|
||||
|
||||
</beans>
|
||||
|
|
|
|||
|
|
@ -40,24 +40,24 @@ public class HypervsiorHostEndPointRpcServer implements HostEndpointRpcServer {
|
|||
private static final Logger s_logger = Logger.getLogger(HypervsiorHostEndPointRpcServer.class);
|
||||
|
||||
@Inject
|
||||
private RpcProvider _rpcProvider;
|
||||
private RpcProvider rpcProvider;
|
||||
|
||||
public HypervsiorHostEndPointRpcServer() {
|
||||
}
|
||||
|
||||
public HypervsiorHostEndPointRpcServer(RpcProvider rpcProvider) {
|
||||
_rpcProvider = rpcProvider;
|
||||
_rpcProvider.registerRpcServiceEndpoint(RpcServiceDispatcher.getDispatcher(this));
|
||||
rpcProvider = rpcProvider;
|
||||
rpcProvider.registerRpcServiceEndpoint(RpcServiceDispatcher.getDispatcher(this));
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void Initialize() {
|
||||
_rpcProvider.registerRpcServiceEndpoint(RpcServiceDispatcher.getDispatcher(this));
|
||||
rpcProvider.registerRpcServiceEndpoint(RpcServiceDispatcher.getDispatcher(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendCommandAsync(HypervisorHostEndPoint host, final Command command, final AsyncCompletionCallback<Answer> callback) {
|
||||
_rpcProvider.newCall(host.getHostAddr()).addCallbackListener(new RpcCallbackListener<Answer>() {
|
||||
rpcProvider.newCall(host.getHostAddr()).addCallbackListener(new RpcCallbackListener<Answer>() {
|
||||
@Override
|
||||
public void onSuccess(Answer result) {
|
||||
callback.complete(result);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,192 @@
|
|||
// 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 org.apache.cloudstack.storage.allocator;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.configuration.dao.ConfigurationDao;
|
||||
import com.cloud.dc.ClusterVO;
|
||||
import com.cloud.dc.dao.ClusterDao;
|
||||
import com.cloud.deploy.DeploymentPlan;
|
||||
import com.cloud.deploy.DeploymentPlanner.ExcludeList;
|
||||
import com.cloud.storage.DiskOfferingVO;
|
||||
import com.cloud.storage.Storage.StoragePoolType;
|
||||
import com.cloud.storage.StorageManager;
|
||||
import com.cloud.storage.StoragePool;
|
||||
import com.cloud.storage.Volume;
|
||||
import com.cloud.storage.Volume.Type;
|
||||
import com.cloud.storage.dao.DiskOfferingDao;
|
||||
import com.cloud.storage.dao.StoragePoolDao;
|
||||
import com.cloud.storage.dao.VolumeDao;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.utils.NumbersUtil;
|
||||
import com.cloud.utils.component.AdapterBase;
|
||||
import com.cloud.vm.DiskProfile;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.VirtualMachineProfile;
|
||||
|
||||
public abstract class AbstractStoragePoolAllocator extends AdapterBase implements StoragePoolAllocator {
|
||||
private static final Logger s_logger = Logger.getLogger(AbstractStoragePoolAllocator.class);
|
||||
@Inject StorageManager storageMgr;
|
||||
protected @Inject StoragePoolDao _storagePoolDao;
|
||||
@Inject VolumeDao _volumeDao;
|
||||
@Inject ConfigurationDao _configDao;
|
||||
@Inject ClusterDao _clusterDao;
|
||||
protected @Inject DataStoreManager dataStoreMgr;
|
||||
protected BigDecimal _storageOverprovisioningFactor = new BigDecimal(1);
|
||||
long _extraBytesPerVolume = 0;
|
||||
Random _rand;
|
||||
boolean _dontMatter;
|
||||
protected String _allocationAlgorithm = "random";
|
||||
@Inject
|
||||
DiskOfferingDao _diskOfferingDao;
|
||||
|
||||
@Override
|
||||
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
|
||||
super.configure(name, params);
|
||||
|
||||
Map<String, String> configs = _configDao.getConfiguration(null, params);
|
||||
|
||||
String globalStorageOverprovisioningFactor = configs.get("storage.overprovisioning.factor");
|
||||
_storageOverprovisioningFactor = new BigDecimal(NumbersUtil.parseFloat(globalStorageOverprovisioningFactor, 2.0f));
|
||||
|
||||
_extraBytesPerVolume = 0;
|
||||
|
||||
_rand = new Random(System.currentTimeMillis());
|
||||
|
||||
_dontMatter = Boolean.parseBoolean(configs.get("storage.overwrite.provisioning"));
|
||||
|
||||
String allocationAlgorithm = configs.get("vm.allocation.algorithm");
|
||||
if (allocationAlgorithm != null) {
|
||||
_allocationAlgorithm = allocationAlgorithm;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected abstract List<StoragePool> select(DiskProfile dskCh, VirtualMachineProfile<? extends VirtualMachine> vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo);
|
||||
|
||||
@Override
|
||||
public
|
||||
List<StoragePool> allocateToPool(DiskProfile dskCh, VirtualMachineProfile<? extends VirtualMachine> vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo) {
|
||||
List<StoragePool> pools = select(dskCh, vmProfile, plan, avoid, returnUpTo);
|
||||
return reOrder(pools, vmProfile, plan);
|
||||
}
|
||||
|
||||
protected List<StoragePool> reorderPoolsByNumberOfVolumes(DeploymentPlan plan, List<StoragePool> pools, Account account) {
|
||||
if(account == null){
|
||||
return pools;
|
||||
}
|
||||
long dcId = plan.getDataCenterId();
|
||||
Long podId = plan.getPodId();
|
||||
Long clusterId = plan.getClusterId();
|
||||
|
||||
List<Long> poolIdsByVolCount = _volumeDao.listPoolIdsByVolumeCount(dcId, podId, clusterId, account.getAccountId());
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("List of pools in ascending order of number of volumes for account id: "+ account.getAccountId() + " is: "+ poolIdsByVolCount);
|
||||
}
|
||||
|
||||
//now filter the given list of Pools by this ordered list
|
||||
Map<Long, StoragePool> poolMap = new HashMap<Long, StoragePool>();
|
||||
for (StoragePool pool : pools) {
|
||||
poolMap.put(pool.getId(), pool);
|
||||
}
|
||||
List<Long> matchingPoolIds = new ArrayList<Long>(poolMap.keySet());
|
||||
|
||||
poolIdsByVolCount.retainAll(matchingPoolIds);
|
||||
|
||||
List<StoragePool> reorderedPools = new ArrayList<StoragePool>();
|
||||
for(Long id: poolIdsByVolCount){
|
||||
reorderedPools.add(poolMap.get(id));
|
||||
}
|
||||
|
||||
return reorderedPools;
|
||||
}
|
||||
|
||||
protected List<StoragePool> reOrder(List<StoragePool> pools,
|
||||
VirtualMachineProfile<? extends VirtualMachine> vmProfile,
|
||||
DeploymentPlan plan) {
|
||||
Account account = null;
|
||||
if(vmProfile.getVirtualMachine() != null){
|
||||
account = vmProfile.getOwner();
|
||||
}
|
||||
|
||||
if(_allocationAlgorithm.equals("random") || _allocationAlgorithm.equals("userconcentratedpod_random") || (account == null)) {
|
||||
// Shuffle this so that we don't check the pools in the same order.
|
||||
Collections.shuffle(pools);
|
||||
}else if(_allocationAlgorithm.equals("userdispersing")){
|
||||
pools = reorderPoolsByNumberOfVolumes(plan, pools, account);
|
||||
}
|
||||
return pools;
|
||||
}
|
||||
|
||||
protected boolean filter(ExcludeList avoid, StoragePool pool, DiskProfile dskCh,
|
||||
DeploymentPlan plan) {
|
||||
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Checking if storage pool is suitable, name: " + pool.getName()+ " ,poolId: "+ pool.getId());
|
||||
}
|
||||
if (avoid.shouldAvoid(pool)) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("StoragePool is in avoid set, skipping this pool");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if(dskCh.getType().equals(Type.ROOT) && pool.getPoolType().equals(StoragePoolType.Iscsi)){
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Disk needed for ROOT volume, but StoragePoolType is Iscsi, skipping this and trying other available pools");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
DiskOfferingVO diskOffering = _diskOfferingDao.findById(dskCh.getDiskOfferingId());
|
||||
if (diskOffering.getSystemUse() && pool.getPoolType() == StoragePoolType.RBD) {
|
||||
s_logger.debug("Skipping RBD pool " + pool.getName() + " as a suitable pool. RBD is not supported for System VM's");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Long clusterId = pool.getClusterId();
|
||||
ClusterVO cluster = _clusterDao.findById(clusterId);
|
||||
if (!(cluster.getHypervisorType() == dskCh.getHypersorType())) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("StoragePool's Cluster does not have required hypervisorType, skipping this pool");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// check capacity
|
||||
Volume volume = _volumeDao.findById(dskCh.getVolumeId());
|
||||
List<Volume> requestVolumes = new ArrayList<Volume>();
|
||||
requestVolumes.add(volume);
|
||||
return storageMgr.storagePoolHasEnoughSpace(requestVolumes, pool);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
// 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 org.apache.cloudstack.storage.allocator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.ejb.Local;
|
||||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
|
||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.cloud.deploy.DeploymentPlan;
|
||||
import com.cloud.deploy.DeploymentPlanner.ExcludeList;
|
||||
import com.cloud.offering.ServiceOffering;
|
||||
import com.cloud.storage.StoragePool;
|
||||
import com.cloud.storage.dao.DiskOfferingDao;
|
||||
import com.cloud.vm.DiskProfile;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.VirtualMachineProfile;
|
||||
|
||||
@Component
|
||||
@Local(value=StoragePoolAllocator.class)
|
||||
public class ClusterScopeStoragePoolAllocator extends AbstractStoragePoolAllocator {
|
||||
private static final Logger s_logger = Logger.getLogger(ClusterScopeStoragePoolAllocator.class);
|
||||
protected String _allocationAlgorithm = "random";
|
||||
|
||||
@Inject
|
||||
DiskOfferingDao _diskOfferingDao;
|
||||
|
||||
@Override
|
||||
protected List<StoragePool> select(DiskProfile dskCh, VirtualMachineProfile<? extends VirtualMachine> vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo) {
|
||||
|
||||
List<StoragePool> suitablePools = new ArrayList<StoragePool>();
|
||||
|
||||
long dcId = plan.getDataCenterId();
|
||||
Long podId = plan.getPodId();
|
||||
Long clusterId = plan.getClusterId();
|
||||
|
||||
if(dskCh.getTags() != null && dskCh.getTags().length != 0){
|
||||
s_logger.debug("Looking for pools in dc: " + dcId + " pod:" + podId + " cluster:" + clusterId + " having tags:" + Arrays.toString(dskCh.getTags()));
|
||||
}else{
|
||||
s_logger.debug("Looking for pools in dc: " + dcId + " pod:" + podId + " cluster:" + clusterId);
|
||||
}
|
||||
|
||||
List<StoragePoolVO> pools = _storagePoolDao.findPoolsByTags(dcId, podId, clusterId, dskCh.getTags());
|
||||
if (pools.size() == 0) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
String storageType = dskCh.useLocalStorage() ? ServiceOffering.StorageType.local.toString() : ServiceOffering.StorageType.shared.toString();
|
||||
s_logger.debug("No storage pools available for " + storageType + " volume allocation, returning");
|
||||
}
|
||||
return suitablePools;
|
||||
}
|
||||
|
||||
for (StoragePoolVO pool: pools) {
|
||||
if(suitablePools.size() == returnUpTo){
|
||||
break;
|
||||
}
|
||||
StoragePool pol = (StoragePool)this.dataStoreMgr.getPrimaryDataStore(pool.getId());
|
||||
if (filter(avoid, pol, dskCh, plan)) {
|
||||
suitablePools.add(pol);
|
||||
}
|
||||
}
|
||||
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("FirstFitStoragePoolAllocator returning "+suitablePools.size() +" suitable storage pools");
|
||||
}
|
||||
|
||||
return suitablePools;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
|
||||
super.configure(name, params);
|
||||
|
||||
if (_configDao != null) {
|
||||
Map<String, String> configs = _configDao.getConfiguration(params);
|
||||
String allocationAlgorithm = configs.get("vm.allocation.algorithm");
|
||||
if (allocationAlgorithm != null) {
|
||||
_allocationAlgorithm = allocationAlgorithm;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package com.cloud.storage.allocator;
|
||||
package org.apache.cloudstack.storage.allocator;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
|
@ -23,8 +23,8 @@ import javax.ejb.Local;
|
|||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.cloud.configuration.dao.ConfigurationDao;
|
||||
import com.cloud.deploy.DeploymentPlan;
|
||||
|
|
@ -36,32 +36,18 @@ import com.cloud.vm.DiskProfile;
|
|||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.VirtualMachineProfile;
|
||||
|
||||
@Component
|
||||
@Local(value=StoragePoolAllocator.class)
|
||||
public class GarbageCollectingStoragePoolAllocator extends AbstractStoragePoolAllocator {
|
||||
private static final Logger s_logger = Logger.getLogger(GarbageCollectingStoragePoolAllocator.class);
|
||||
|
||||
StoragePoolAllocator _firstFitStoragePoolAllocator;
|
||||
StoragePoolAllocator _localStoragePoolAllocator;
|
||||
@Inject StorageManager _storageMgr;
|
||||
@Inject StorageManager storageMgr;
|
||||
@Inject ConfigurationDao _configDao;
|
||||
boolean _storagePoolCleanupEnabled;
|
||||
|
||||
@Override
|
||||
public boolean allocatorIsCorrectType(DiskProfile dskCh) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public Integer getStorageOverprovisioningFactor() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Long getExtraBytesPerVolume() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StoragePool> allocateToPool(DiskProfile dskCh, VirtualMachineProfile<? extends VirtualMachine> vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo) {
|
||||
public List<StoragePool> select(DiskProfile dskCh, VirtualMachineProfile<? extends VirtualMachine> vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo) {
|
||||
|
||||
if (!_storagePoolCleanupEnabled) {
|
||||
s_logger.debug("Storage pool cleanup is not enabled, so GarbageCollectingStoragePoolAllocator is being skipped.");
|
||||
|
|
@ -69,10 +55,10 @@ public class GarbageCollectingStoragePoolAllocator extends AbstractStoragePoolAl
|
|||
}
|
||||
|
||||
// Clean up all storage pools
|
||||
_storageMgr.cleanupStorage(false);
|
||||
storageMgr.cleanupStorage(false);
|
||||
// Determine what allocator to use
|
||||
StoragePoolAllocator allocator;
|
||||
if (localStorageAllocationNeeded(dskCh)) {
|
||||
if (dskCh.useLocalStorage()) {
|
||||
allocator = _localStoragePoolAllocator;
|
||||
} else {
|
||||
allocator = _firstFitStoragePoolAllocator;
|
||||
|
|
@ -88,7 +74,7 @@ public class GarbageCollectingStoragePoolAllocator extends AbstractStoragePoolAl
|
|||
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
|
||||
super.configure(name, params);
|
||||
|
||||
_firstFitStoragePoolAllocator = ComponentContext.inject(FirstFitStoragePoolAllocator.class);
|
||||
_firstFitStoragePoolAllocator = ComponentContext.inject(ClusterScopeStoragePoolAllocator.class);
|
||||
_firstFitStoragePoolAllocator.configure("GCFirstFitStoragePoolAllocator", params);
|
||||
_localStoragePoolAllocator = ComponentContext.inject(LocalStoragePoolAllocator.class);
|
||||
_localStoragePoolAllocator.configure("GCLocalStoragePoolAllocator", params);
|
||||
|
|
@ -0,0 +1,126 @@
|
|||
// 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 org.apache.cloudstack.storage.allocator;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.ejb.Local;
|
||||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
|
||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.cloud.capacity.dao.CapacityDao;
|
||||
import com.cloud.configuration.dao.ConfigurationDao;
|
||||
import com.cloud.deploy.DeploymentPlan;
|
||||
import com.cloud.deploy.DeploymentPlanner.ExcludeList;
|
||||
import com.cloud.service.dao.ServiceOfferingDao;
|
||||
import com.cloud.storage.StoragePool;
|
||||
import com.cloud.storage.StoragePoolHostVO;
|
||||
import com.cloud.storage.Volume;
|
||||
import com.cloud.storage.dao.StoragePoolHostDao;
|
||||
import com.cloud.utils.NumbersUtil;
|
||||
import com.cloud.vm.DiskProfile;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.VirtualMachineProfile;
|
||||
import com.cloud.vm.dao.UserVmDao;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
|
||||
@Component
|
||||
@Local(value = StoragePoolAllocator.class)
|
||||
public class LocalStoragePoolAllocator extends AbstractStoragePoolAllocator {
|
||||
private static final Logger s_logger = Logger.getLogger(LocalStoragePoolAllocator.class);
|
||||
|
||||
@Inject
|
||||
StoragePoolHostDao _poolHostDao;
|
||||
@Inject
|
||||
VMInstanceDao _vmInstanceDao;
|
||||
@Inject
|
||||
UserVmDao _vmDao;
|
||||
@Inject
|
||||
ServiceOfferingDao _offeringDao;
|
||||
@Inject
|
||||
CapacityDao _capacityDao;
|
||||
@Inject
|
||||
ConfigurationDao _configDao;
|
||||
|
||||
@Override
|
||||
protected List<StoragePool> select(DiskProfile dskCh, VirtualMachineProfile<? extends VirtualMachine> vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo) {
|
||||
|
||||
List<StoragePool> suitablePools = new ArrayList<StoragePool>();
|
||||
|
||||
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("LocalStoragePoolAllocator trying to find storage pool to fit the vm");
|
||||
}
|
||||
|
||||
// data disk and host identified from deploying vm (attach volume case)
|
||||
if (dskCh.getType() == Volume.Type.DATADISK && plan.getHostId() != null) {
|
||||
List<StoragePoolHostVO> hostPools = _poolHostDao.listByHostId(plan.getHostId());
|
||||
for (StoragePoolHostVO hostPool: hostPools) {
|
||||
StoragePoolVO pool = _storagePoolDao.findById(hostPool.getPoolId());
|
||||
if (pool != null && pool.isLocal()) {
|
||||
StoragePool pol = (StoragePool)this.dataStoreMgr.getPrimaryDataStore(pool.getId());
|
||||
if (filter(avoid, pol, dskCh, plan)) {
|
||||
s_logger.debug("Found suitable local storage pool " + pool.getId() + ", adding to list");
|
||||
suitablePools.add(pol);
|
||||
}
|
||||
}
|
||||
|
||||
if (suitablePools.size() == returnUpTo) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
List<StoragePoolVO> availablePools = _storagePoolDao.findLocalStoragePoolsByTags(plan.getDataCenterId(), plan.getPodId(), plan.getClusterId(), dskCh.getTags());
|
||||
for (StoragePoolVO pool : availablePools) {
|
||||
if (suitablePools.size() == returnUpTo) {
|
||||
break;
|
||||
}
|
||||
StoragePool pol = (StoragePool)this.dataStoreMgr.getPrimaryDataStore(pool.getId());
|
||||
if (filter(avoid, pol, dskCh, plan)) {
|
||||
suitablePools.add(pol);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("LocalStoragePoolAllocator returning " + suitablePools.size() + " suitable storage pools");
|
||||
}
|
||||
|
||||
return suitablePools;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
|
||||
super.configure(name, params);
|
||||
|
||||
_storageOverprovisioningFactor = new BigDecimal(1);
|
||||
_extraBytesPerVolume = NumbersUtil.parseLong((String) params.get("extra.bytes.per.volume"), 50 * 1024L * 1024L);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public LocalStoragePoolAllocator() {
|
||||
}
|
||||
}
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package com.cloud.storage.allocator;
|
||||
package org.apache.cloudstack.storage.allocator;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
|
@ -23,23 +23,17 @@ import javax.ejb.Local;
|
|||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
|
||||
|
||||
import com.cloud.configuration.Config;
|
||||
import com.cloud.configuration.dao.ConfigurationDao;
|
||||
import com.cloud.dc.DataCenterVO;
|
||||
import com.cloud.dc.dao.DataCenterDao;
|
||||
import com.cloud.deploy.DeploymentPlan;
|
||||
import com.cloud.deploy.DeploymentPlanner.ExcludeList;
|
||||
import com.cloud.host.Host;
|
||||
import com.cloud.storage.StoragePool;
|
||||
import com.cloud.storage.Volume.Type;
|
||||
|
||||
import com.cloud.vm.DiskProfile;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.VirtualMachineProfile;
|
||||
|
||||
@Component
|
||||
@Local(value=StoragePoolAllocator.class)
|
||||
public class UseLocalForRootAllocator extends LocalStoragePoolAllocator implements StoragePoolAllocator {
|
||||
|
||||
|
|
@ -55,29 +49,13 @@ public class UseLocalForRootAllocator extends LocalStoragePoolAllocator implemen
|
|||
|
||||
return super.allocateToPool(dskCh, vmProfile, plan, avoid, returnUpTo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String chooseStorageIp(VirtualMachine vm, Host host, Host storage) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
|
||||
super.configure(name, params);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean localStorageAllocationNeeded(DiskProfile dskCh) {
|
||||
if (dskCh.getType() == Type.ROOT) {
|
||||
return true;
|
||||
} else if (dskCh.getType() == Type.DATADISK) {
|
||||
return false;
|
||||
} else {
|
||||
return super.localStorageAllocationNeeded(dskCh);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected UseLocalForRootAllocator() {
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
package org.apache.cloudstack.storage.allocator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
|
||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.cloud.deploy.DeploymentPlan;
|
||||
import com.cloud.deploy.DeploymentPlanner.ExcludeList;
|
||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
import com.cloud.storage.StoragePool;
|
||||
import com.cloud.storage.Volume;
|
||||
import com.cloud.storage.dao.StoragePoolDao;
|
||||
import com.cloud.vm.DiskProfile;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.VirtualMachineProfile;
|
||||
|
||||
@Component
|
||||
public class ZoneWideStoragePoolAllocator extends AbstractStoragePoolAllocator {
|
||||
private static final Logger s_logger = Logger.getLogger(ZoneWideStoragePoolAllocator.class);
|
||||
@Inject StoragePoolDao _storagePoolDao;
|
||||
@Inject DataStoreManager dataStoreMgr;
|
||||
|
||||
@Override
|
||||
protected boolean filter(ExcludeList avoid, StoragePool pool, DiskProfile dskCh,
|
||||
DeploymentPlan plan) {
|
||||
Volume volume = _volumeDao.findById(dskCh.getVolumeId());
|
||||
List<Volume> requestVolumes = new ArrayList<Volume>();
|
||||
requestVolumes.add(volume);
|
||||
return storageMgr.storagePoolHasEnoughSpace(requestVolumes, pool);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<StoragePool> select(DiskProfile dskCh,
|
||||
VirtualMachineProfile<? extends VirtualMachine> vmProfile,
|
||||
DeploymentPlan plan, ExcludeList avoid, int returnUpTo) {
|
||||
List<StoragePool> suitablePools = new ArrayList<StoragePool>();
|
||||
HypervisorType hypervisor = vmProfile.getHypervisorType();
|
||||
if (hypervisor != null) {
|
||||
if (hypervisor != HypervisorType.KVM) {
|
||||
s_logger.debug("Only kvm supports zone wide storage");
|
||||
return suitablePools;
|
||||
}
|
||||
}
|
||||
|
||||
List<StoragePoolVO> storagePools = _storagePoolDao.findZoneWideStoragePoolsByTags(plan.getDataCenterId(), dskCh.getTags());
|
||||
|
||||
for (StoragePoolVO storage : storagePools) {
|
||||
if (suitablePools.size() == returnUpTo) {
|
||||
break;
|
||||
}
|
||||
StoragePool pol = (StoragePool)this.dataStoreMgr.getPrimaryDataStore(storage.getId());
|
||||
if (filter(avoid, pol, dskCh, plan)) {
|
||||
suitablePools.add(pol);
|
||||
}
|
||||
}
|
||||
return suitablePools;
|
||||
}
|
||||
}
|
||||
|
|
@ -100,7 +100,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy {
|
|||
@Inject
|
||||
ConfigurationDao configDao;
|
||||
@Inject
|
||||
StorageManager storagMgr;
|
||||
StorageManager storageMgr;
|
||||
@Inject
|
||||
VolumeDao volDao;
|
||||
@Inject
|
||||
|
|
@ -149,7 +149,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy {
|
|||
CopyVolumeAnswer cvAnswer = null;
|
||||
String errMsg = null;
|
||||
try {
|
||||
cvAnswer = (CopyVolumeAnswer) this.storagMgr.sendToPool(destPool,
|
||||
cvAnswer = (CopyVolumeAnswer) this.storageMgr.sendToPool(destPool,
|
||||
cvCmd);
|
||||
} catch (StorageUnavailableException e1) {
|
||||
s_logger.debug("Failed to copy volume " + srcData.getId() + " to "
|
||||
|
|
@ -231,7 +231,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy {
|
|||
"2.1");
|
||||
Answer answer = null;
|
||||
try {
|
||||
answer = this.storagMgr.sendToPool(pool, cmd);
|
||||
answer = this.storageMgr.sendToPool(pool, cmd);
|
||||
} catch (StorageUnavailableException e) {
|
||||
} finally {
|
||||
snapshotDao.unlockFromLockTable(snapshotId.toString());
|
||||
|
|
@ -268,7 +268,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy {
|
|||
+ snapshotId
|
||||
+ " due to this snapshot is being used, try it later ");
|
||||
}
|
||||
answer = (CreateVolumeFromSnapshotAnswer) this.storagMgr
|
||||
answer = (CreateVolumeFromSnapshotAnswer) this.storageMgr
|
||||
.sendToPool(pool, createVolumeFromSnapshotCommand);
|
||||
if (answer != null && answer.getResult()) {
|
||||
vdiUUID = answer.getVdi();
|
||||
|
|
@ -306,7 +306,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy {
|
|||
StoragePool pool = (StoragePool)volume.getDataStore();
|
||||
String errMsg = null;
|
||||
try {
|
||||
answer = storagMgr.sendToPool(pool, null, cmd);
|
||||
answer = storageMgr.sendToPool(pool, null, cmd);
|
||||
} catch (StorageUnavailableException e) {
|
||||
s_logger.debug("Failed to send to storage pool", e);
|
||||
throw new CloudRuntimeException("Failed to send to storage pool", e);
|
||||
|
|
@ -358,7 +358,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy {
|
|||
_copyvolumewait);
|
||||
CopyVolumeAnswer cvAnswer;
|
||||
try {
|
||||
cvAnswer = (CopyVolumeAnswer) this.storagMgr.sendToPool(srcPool, cvCmd);
|
||||
cvAnswer = (CopyVolumeAnswer) this.storageMgr.sendToPool(srcPool, cvCmd);
|
||||
} catch (StorageUnavailableException e1) {
|
||||
throw new CloudRuntimeException(
|
||||
"Failed to copy the volume from the source primary storage pool to secondary storage.",
|
||||
|
|
@ -376,7 +376,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy {
|
|||
secondaryStorageVolumePath, destPool,
|
||||
secondaryStorageURL, false, _copyvolumewait);
|
||||
try {
|
||||
cvAnswer = (CopyVolumeAnswer) this.storagMgr.sendToPool(destPool, cvCmd);
|
||||
cvAnswer = (CopyVolumeAnswer) this.storageMgr.sendToPool(destPool, cvCmd);
|
||||
} catch (StorageUnavailableException e1) {
|
||||
throw new CloudRuntimeException(
|
||||
"Failed to copy the volume from secondary storage to the destination primary storage pool.");
|
||||
|
|
@ -464,7 +464,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy {
|
|||
Long volumeId = snapshot.getVolumeId();
|
||||
|
||||
String origTemplateInstallPath = null;
|
||||
List<StoragePoolVO> pools = this.storagMgr
|
||||
List<StoragePoolVO> pools = this.storageMgr
|
||||
.ListByDataCenterHypervisor(zoneId,
|
||||
snapshot.getHypervisorType());
|
||||
if (pools == null || pools.size() == 0) {
|
||||
|
|
@ -516,7 +516,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy {
|
|||
}
|
||||
Answer answer = null;
|
||||
try {
|
||||
answer = this.storagMgr.sendToPool(pool, cmd);
|
||||
answer = this.storageMgr.sendToPool(pool, cmd);
|
||||
cmd = null;
|
||||
} catch (StorageUnavailableException e) {
|
||||
} finally {
|
||||
|
|
@ -557,7 +557,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy {
|
|||
|
||||
CreatePrivateTemplateAnswer answer = null;
|
||||
try {
|
||||
answer = (CreatePrivateTemplateAnswer) this.storagMgr.sendToPool(
|
||||
answer = (CreatePrivateTemplateAnswer) this.storageMgr.sendToPool(
|
||||
pool, cmd);
|
||||
} catch (StorageUnavailableException e) {
|
||||
throw new CloudRuntimeException(
|
||||
|
|
|
|||
|
|
@ -94,10 +94,10 @@ import com.cloud.vm.dao.SecondaryStorageVmDao;
|
|||
import com.cloud.vm.dao.UserVmDao;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
|
||||
public class AncientPrimaryDataStoreLifeCyclImpl implements
|
||||
public class AncientPrimaryDataStoreLifeCycleImpl implements
|
||||
PrimaryDataStoreLifeCycle {
|
||||
private static final Logger s_logger = Logger
|
||||
.getLogger(AncientPrimaryDataStoreLifeCyclImpl.class);
|
||||
.getLogger(AncientPrimaryDataStoreLifeCycleImpl.class);
|
||||
@Inject
|
||||
protected ResourceManager _resourceMgr;
|
||||
protected List<StoragePoolDiscoverer> _discoverers;
|
||||
|
|
@ -134,9 +134,6 @@ public class AncientPrimaryDataStoreLifeCyclImpl implements
|
|||
protected StoragePoolHostDao _storagePoolHostDao;
|
||||
@Inject
|
||||
protected AlertManager _alertMgr;
|
||||
|
||||
|
||||
|
||||
@Inject
|
||||
protected ConsoleProxyDao _consoleProxyDao;
|
||||
|
||||
|
|
@ -27,7 +27,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener
|
|||
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver;
|
||||
import org.apache.cloudstack.storage.datastore.PrimaryDataStoreProviderManager;
|
||||
import org.apache.cloudstack.storage.datastore.driver.AncientPrimaryDataStoreDriverImpl;
|
||||
import org.apache.cloudstack.storage.datastore.lifecycle.AncientPrimaryDataStoreLifeCyclImpl;
|
||||
import org.apache.cloudstack.storage.datastore.lifecycle.AncientPrimaryDataStoreLifeCycleImpl;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.cloud.utils.component.ComponentContext;
|
||||
|
|
@ -55,7 +55,7 @@ public class AncientPrimaryDataStoreProviderImpl implements
|
|||
|
||||
@Override
|
||||
public boolean configure(Map<String, Object> params) {
|
||||
lifecyle = ComponentContext.inject(AncientPrimaryDataStoreLifeCyclImpl.class);
|
||||
lifecyle = ComponentContext.inject(AncientPrimaryDataStoreLifeCycleImpl.class);
|
||||
driver = ComponentContext.inject(AncientPrimaryDataStoreDriverImpl.class);
|
||||
uuid = (String)params.get("uuid");
|
||||
id = (Long)params.get("id");
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ public class XcpOssResource extends CitrixResourceBase {
|
|||
@Override
|
||||
protected List<File> getPatchFiles() {
|
||||
List<File> files = new ArrayList<File>();
|
||||
String patch = "scripts/vm/hypervisor/xenserver/xcposs/patch";
|
||||
String patch = "patch";
|
||||
String patchfilePath = Script.findScript("", patch);
|
||||
if (patchfilePath == null) {
|
||||
throw new CloudRuntimeException("Unable to find patch file " + patch);
|
||||
|
|
|
|||
|
|
@ -26,4 +26,12 @@
|
|||
<version>4.2.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.cloudstack</groupId>
|
||||
<artifactId>cloud-engine-storage</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
|
|||
|
|
@ -1,91 +0,0 @@
|
|||
// 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.storage.allocator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import javax.ejb.Local;
|
||||
|
||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.cloud.deploy.DeploymentPlan;
|
||||
import com.cloud.deploy.DeploymentPlanner.ExcludeList;
|
||||
import com.cloud.server.StatsCollector;
|
||||
import com.cloud.storage.StoragePool;
|
||||
import com.cloud.storage.VMTemplateVO;
|
||||
import com.cloud.vm.DiskProfile;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.VirtualMachineProfile;
|
||||
|
||||
@Component
|
||||
@Local(value=StoragePoolAllocator.class)
|
||||
public class RandomStoragePoolAllocator extends AbstractStoragePoolAllocator {
|
||||
private static final Logger s_logger = Logger.getLogger(RandomStoragePoolAllocator.class);
|
||||
|
||||
@Override
|
||||
public boolean allocatorIsCorrectType(DiskProfile dskCh) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StoragePool> allocateToPool(DiskProfile dskCh, VirtualMachineProfile<? extends VirtualMachine> vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo) {
|
||||
|
||||
List<StoragePool> suitablePools = new ArrayList<StoragePool>();
|
||||
|
||||
VMTemplateVO template = (VMTemplateVO)vmProfile.getTemplate();
|
||||
// Check that the allocator type is correct
|
||||
if (!allocatorIsCorrectType(dskCh)) {
|
||||
return suitablePools;
|
||||
}
|
||||
long dcId = plan.getDataCenterId();
|
||||
Long podId = plan.getPodId();
|
||||
Long clusterId = plan.getClusterId();
|
||||
s_logger.debug("Looking for pools in dc: " + dcId + " pod:" + podId + " cluster:" + clusterId);
|
||||
List<StoragePoolVO> pools = _storagePoolDao.listBy(dcId, podId, clusterId);
|
||||
if (pools.size() == 0) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("No storage pools available for allocation, returning");
|
||||
}
|
||||
return suitablePools;
|
||||
}
|
||||
|
||||
StatsCollector sc = StatsCollector.getInstance();
|
||||
|
||||
Collections.shuffle(pools);
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("RandomStoragePoolAllocator has " + pools.size() + " pools to check for allocation");
|
||||
}
|
||||
for (StoragePoolVO pool: pools) {
|
||||
if(suitablePools.size() == returnUpTo){
|
||||
break;
|
||||
}
|
||||
if (checkPool(avoid, pool, dskCh, template, null, sc, plan)) {
|
||||
StoragePool pol = (StoragePool)this.dataStoreMgr.getPrimaryDataStore(pool.getId());
|
||||
suitablePools.add(pol);
|
||||
}
|
||||
}
|
||||
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("RandomStoragePoolAllocator returning "+suitablePools.size() +" suitable storage pools");
|
||||
}
|
||||
|
||||
return suitablePools;
|
||||
}
|
||||
}
|
||||
2
pom.xml
2
pom.xml
|
|
@ -161,9 +161,9 @@
|
|||
<module>usage</module>
|
||||
<module>utils</module>
|
||||
<module>deps/XenServerJava</module>
|
||||
<module>engine</module>
|
||||
<module>plugins</module>
|
||||
<module>patches</module>
|
||||
<module>engine</module>
|
||||
<module>framework</module>
|
||||
<module>services</module>
|
||||
<module>test</module>
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ package com.cloud.cluster.agentlb.dao;
|
|||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.ejb.Local;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
|
@ -37,30 +38,35 @@ import com.cloud.utils.db.SearchCriteria;
|
|||
public class HostTransferMapDaoImpl extends GenericDaoBase<HostTransferMapVO, Long> implements HostTransferMapDao {
|
||||
private static final Logger s_logger = Logger.getLogger(HostTransferMapDaoImpl.class);
|
||||
|
||||
protected final SearchBuilder<HostTransferMapVO> AllFieldsSearch;
|
||||
protected final SearchBuilder<HostTransferMapVO> IntermediateStateSearch;
|
||||
protected final SearchBuilder<HostTransferMapVO> ActiveSearch;
|
||||
protected SearchBuilder<HostTransferMapVO> AllFieldsSearch;
|
||||
protected SearchBuilder<HostTransferMapVO> IntermediateStateSearch;
|
||||
protected SearchBuilder<HostTransferMapVO> ActiveSearch;
|
||||
|
||||
public HostTransferMapDaoImpl() {
|
||||
AllFieldsSearch = createSearchBuilder();
|
||||
AllFieldsSearch.and("id", AllFieldsSearch.entity().getId(), SearchCriteria.Op.EQ);
|
||||
AllFieldsSearch.and("initialOwner", AllFieldsSearch.entity().getInitialOwner(), SearchCriteria.Op.EQ);
|
||||
AllFieldsSearch.and("futureOwner", AllFieldsSearch.entity().getFutureOwner(), SearchCriteria.Op.EQ);
|
||||
AllFieldsSearch.and("state", AllFieldsSearch.entity().getState(), SearchCriteria.Op.EQ);
|
||||
AllFieldsSearch.done();
|
||||
|
||||
IntermediateStateSearch = createSearchBuilder();
|
||||
IntermediateStateSearch.and("futureOwner", IntermediateStateSearch.entity().getFutureOwner(), SearchCriteria.Op.EQ);
|
||||
IntermediateStateSearch.and("initialOwner", IntermediateStateSearch.entity().getInitialOwner(), SearchCriteria.Op.EQ);
|
||||
IntermediateStateSearch.and("state", IntermediateStateSearch.entity().getState(), SearchCriteria.Op.IN);
|
||||
IntermediateStateSearch.done();
|
||||
|
||||
ActiveSearch = createSearchBuilder();
|
||||
ActiveSearch.and("created", ActiveSearch.entity().getCreated(), SearchCriteria.Op.GT);
|
||||
ActiveSearch.and("id", ActiveSearch.entity().getId(), SearchCriteria.Op.EQ);
|
||||
ActiveSearch.and("state", ActiveSearch.entity().getState(), SearchCriteria.Op.EQ);
|
||||
ActiveSearch.done();
|
||||
|
||||
super();
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
AllFieldsSearch = createSearchBuilder();
|
||||
AllFieldsSearch.and("id", AllFieldsSearch.entity().getId(), SearchCriteria.Op.EQ);
|
||||
AllFieldsSearch.and("initialOwner", AllFieldsSearch.entity().getInitialOwner(), SearchCriteria.Op.EQ);
|
||||
AllFieldsSearch.and("futureOwner", AllFieldsSearch.entity().getFutureOwner(), SearchCriteria.Op.EQ);
|
||||
AllFieldsSearch.and("state", AllFieldsSearch.entity().getState(), SearchCriteria.Op.EQ);
|
||||
AllFieldsSearch.done();
|
||||
|
||||
IntermediateStateSearch = createSearchBuilder();
|
||||
IntermediateStateSearch.and("futureOwner", IntermediateStateSearch.entity().getFutureOwner(), SearchCriteria.Op.EQ);
|
||||
IntermediateStateSearch.and("initialOwner", IntermediateStateSearch.entity().getInitialOwner(), SearchCriteria.Op.EQ);
|
||||
IntermediateStateSearch.and("state", IntermediateStateSearch.entity().getState(), SearchCriteria.Op.IN);
|
||||
IntermediateStateSearch.done();
|
||||
|
||||
ActiveSearch = createSearchBuilder();
|
||||
ActiveSearch.and("created", ActiveSearch.entity().getCreated(), SearchCriteria.Op.GT);
|
||||
ActiveSearch.and("id", ActiveSearch.entity().getId(), SearchCriteria.Op.EQ);
|
||||
ActiveSearch.and("state", ActiveSearch.entity().getState(), SearchCriteria.Op.EQ);
|
||||
ActiveSearch.done();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ import java.util.ArrayList;
|
|||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
|
||||
|
||||
import com.cloud.agent.AgentManager;
|
||||
import com.cloud.consoleproxy.ConsoleProxyManager;
|
||||
import com.cloud.ha.HighAvailabilityManager;
|
||||
|
|
@ -28,7 +30,6 @@ import com.cloud.network.NetworkManager;
|
|||
import com.cloud.network.router.VpcVirtualNetworkApplianceManager;
|
||||
import com.cloud.server.ManagementServer;
|
||||
import com.cloud.storage.StorageManager;
|
||||
import com.cloud.storage.allocator.StoragePoolAllocator;
|
||||
import com.cloud.storage.secondary.SecondaryStorageVmManager;
|
||||
import com.cloud.storage.snapshot.SnapshotManager;
|
||||
import com.cloud.template.TemplateManager;
|
||||
|
|
|
|||
|
|
@ -28,17 +28,23 @@ import javax.inject.Inject;
|
|||
import javax.naming.ConfigurationException;
|
||||
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
|
||||
import com.cloud.dc.*;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.agent.manager.allocator.HostAllocator;
|
||||
import com.cloud.api.ApiDBUtils;
|
||||
import com.cloud.capacity.Capacity;
|
||||
import com.cloud.capacity.CapacityManager;
|
||||
import com.cloud.capacity.CapacityVO;
|
||||
import com.cloud.capacity.dao.CapacityDao;
|
||||
import com.cloud.configuration.Config;
|
||||
import com.cloud.configuration.dao.ConfigurationDao;
|
||||
import com.cloud.dc.ClusterDetailsDao;
|
||||
import com.cloud.dc.ClusterDetailsVO;
|
||||
import com.cloud.dc.ClusterVO;
|
||||
import com.cloud.dc.DataCenter;
|
||||
import com.cloud.dc.DataCenterVO;
|
||||
import com.cloud.dc.HostPodVO;
|
||||
import com.cloud.dc.Pod;
|
||||
import com.cloud.dc.dao.ClusterDao;
|
||||
import com.cloud.dc.dao.DataCenterDao;
|
||||
import com.cloud.dc.dao.HostPodDao;
|
||||
|
|
@ -58,7 +64,6 @@ import com.cloud.storage.StoragePool;
|
|||
import com.cloud.storage.StoragePoolHostVO;
|
||||
import com.cloud.storage.Volume;
|
||||
import com.cloud.storage.VolumeVO;
|
||||
import com.cloud.storage.allocator.StoragePoolAllocator;
|
||||
import com.cloud.storage.dao.DiskOfferingDao;
|
||||
import com.cloud.storage.dao.GuestOSCategoryDao;
|
||||
import com.cloud.storage.dao.GuestOSDao;
|
||||
|
|
|
|||
|
|
@ -128,6 +128,7 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
|
|||
@Inject protected ClusterDao _clusterDao;
|
||||
|
||||
public HostDaoImpl() {
|
||||
super();
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
|
|
@ -261,7 +262,11 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
|
|||
* UnmanagedDirectConnectSearch.and("lastPinged", UnmanagedDirectConnectSearch.entity().getLastPinged(),
|
||||
* SearchCriteria.Op.LTEQ); UnmanagedDirectConnectSearch.cp(); UnmanagedDirectConnectSearch.cp();
|
||||
*/
|
||||
try {
|
||||
HostTransferSearch = _hostTransferDao.createSearchBuilder();
|
||||
} catch (Throwable e) {
|
||||
s_logger.debug("error", e);
|
||||
}
|
||||
HostTransferSearch.and("id", HostTransferSearch.entity().getId(), SearchCriteria.Op.NULL);
|
||||
UnmanagedDirectConnectSearch.join("hostTransferSearch", HostTransferSearch, HostTransferSearch.entity().getId(), UnmanagedDirectConnectSearch.entity().getId(), JoinType.LEFTOUTER);
|
||||
ClusterManagedSearch = _clusterDao.createSearchBuilder();
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.ImageDataFactory;
|
|||
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.ScopeType;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult;
|
||||
|
|
@ -69,7 +70,6 @@ import org.apache.log4j.Logger;
|
|||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.cloud.agent.AgentManager;
|
||||
|
||||
import com.cloud.agent.api.Answer;
|
||||
import com.cloud.agent.api.BackupSnapshotCommand;
|
||||
import com.cloud.agent.api.CleanupSnapshotBackupCommand;
|
||||
|
|
@ -78,7 +78,6 @@ import com.cloud.agent.api.ManageSnapshotCommand;
|
|||
import com.cloud.agent.api.StoragePoolInfo;
|
||||
import com.cloud.agent.api.storage.DeleteTemplateCommand;
|
||||
import com.cloud.agent.api.storage.DeleteVolumeCommand;
|
||||
|
||||
import com.cloud.agent.manager.Commands;
|
||||
import com.cloud.alert.AlertManager;
|
||||
import com.cloud.api.ApiDBUtils;
|
||||
|
|
@ -100,10 +99,10 @@ import com.cloud.dc.HostPodVO;
|
|||
import com.cloud.dc.dao.ClusterDao;
|
||||
import com.cloud.dc.dao.DataCenterDao;
|
||||
import com.cloud.dc.dao.HostPodDao;
|
||||
import com.cloud.deploy.DataCenterDeployment;
|
||||
import com.cloud.deploy.DeploymentPlanner.ExcludeList;
|
||||
import com.cloud.domain.dao.DomainDao;
|
||||
|
||||
import com.cloud.event.dao.EventDao;
|
||||
import com.cloud.event.dao.UsageEventDao;
|
||||
import com.cloud.exception.AgentUnavailableException;
|
||||
import com.cloud.exception.ConnectionException;
|
||||
import com.cloud.exception.InsufficientCapacityException;
|
||||
|
|
@ -113,7 +112,6 @@ import com.cloud.exception.PermissionDeniedException;
|
|||
import com.cloud.exception.ResourceInUseException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.exception.StorageUnavailableException;
|
||||
|
||||
import com.cloud.host.Host;
|
||||
import com.cloud.host.HostVO;
|
||||
import com.cloud.host.Status;
|
||||
|
|
@ -132,8 +130,6 @@ import com.cloud.service.dao.ServiceOfferingDao;
|
|||
import com.cloud.storage.Storage.ImageFormat;
|
||||
import com.cloud.storage.Storage.StoragePoolType;
|
||||
import com.cloud.storage.Volume.Type;
|
||||
import com.cloud.storage.allocator.StoragePoolAllocator;
|
||||
|
||||
import com.cloud.storage.dao.DiskOfferingDao;
|
||||
import com.cloud.storage.dao.SnapshotDao;
|
||||
import com.cloud.storage.dao.SnapshotPolicyDao;
|
||||
|
|
@ -146,7 +142,6 @@ import com.cloud.storage.dao.VMTemplateS3Dao;
|
|||
import com.cloud.storage.dao.VMTemplateSwiftDao;
|
||||
import com.cloud.storage.dao.VolumeDao;
|
||||
import com.cloud.storage.dao.VolumeHostDao;
|
||||
|
||||
import com.cloud.storage.download.DownloadMonitor;
|
||||
import com.cloud.storage.listener.StoragePoolMonitor;
|
||||
import com.cloud.storage.listener.VolumeStateListener;
|
||||
|
|
@ -156,7 +151,11 @@ import com.cloud.storage.snapshot.SnapshotManager;
|
|||
import com.cloud.storage.snapshot.SnapshotScheduler;
|
||||
import com.cloud.tags.dao.ResourceTagDao;
|
||||
import com.cloud.template.TemplateManager;
|
||||
import com.cloud.user.*;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountManager;
|
||||
import com.cloud.user.ResourceLimitService;
|
||||
import com.cloud.user.User;
|
||||
import com.cloud.user.UserContext;
|
||||
import com.cloud.user.dao.AccountDao;
|
||||
import com.cloud.user.dao.UserDao;
|
||||
import com.cloud.utils.NumbersUtil;
|
||||
|
|
@ -165,20 +164,28 @@ import com.cloud.utils.UriUtils;
|
|||
import com.cloud.utils.component.ComponentContext;
|
||||
import com.cloud.utils.component.ManagerBase;
|
||||
import com.cloud.utils.concurrency.NamedThreadFactory;
|
||||
import com.cloud.utils.db.*;
|
||||
import com.cloud.utils.db.DB;
|
||||
import com.cloud.utils.db.GenericSearchBuilder;
|
||||
import com.cloud.utils.db.GlobalLock;
|
||||
import com.cloud.utils.db.JoinBuilder;
|
||||
import com.cloud.utils.db.JoinBuilder.JoinType;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.utils.db.SearchCriteria.Op;
|
||||
import com.cloud.utils.db.Transaction;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
|
||||
import com.cloud.vm.DiskProfile;
|
||||
import com.cloud.vm.UserVmManager;
|
||||
import com.cloud.vm.VMInstanceVO;
|
||||
import com.cloud.vm.VirtualMachine.State;
|
||||
import com.cloud.vm.VirtualMachineManager;
|
||||
import com.cloud.vm.VirtualMachineProfile;
|
||||
import com.cloud.vm.VirtualMachineProfileImpl;
|
||||
|
||||
import com.cloud.vm.VirtualMachine.State;
|
||||
import com.cloud.vm.dao.*;
|
||||
import com.cloud.vm.dao.ConsoleProxyDao;
|
||||
import com.cloud.vm.dao.DomainRouterDao;
|
||||
import com.cloud.vm.dao.SecondaryStorageVmDao;
|
||||
import com.cloud.vm.dao.UserVmDao;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
|
||||
@Component
|
||||
@Local(value = { StorageManager.class, StorageService.class })
|
||||
|
|
@ -193,24 +200,10 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||
@Inject
|
||||
protected TemplateManager _tmpltMgr;
|
||||
@Inject
|
||||
protected AsyncJobManager _asyncMgr;
|
||||
@Inject
|
||||
protected SnapshotManager _snapshotMgr;
|
||||
@Inject
|
||||
protected SnapshotScheduler _snapshotScheduler;
|
||||
@Inject
|
||||
protected AccountManager _accountMgr;
|
||||
@Inject
|
||||
protected ConfigurationManager _configMgr;
|
||||
@Inject
|
||||
protected ConsoleProxyManager _consoleProxyMgr;
|
||||
@Inject
|
||||
protected SecondaryStorageVmManager _secStorageMgr;
|
||||
@Inject
|
||||
protected NetworkModel _networkMgr;
|
||||
@Inject
|
||||
protected ServiceOfferingDao _serviceOfferingDao;
|
||||
@Inject
|
||||
protected VolumeDao _volsDao;
|
||||
@Inject
|
||||
protected HostDao _hostDao;
|
||||
|
|
@ -275,30 +268,14 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||
@Inject
|
||||
protected ClusterDao _clusterDao;
|
||||
@Inject
|
||||
protected VirtualMachineManager _vmMgr;
|
||||
@Inject
|
||||
protected DomainRouterDao _domrDao;
|
||||
@Inject
|
||||
protected SecondaryStorageVmDao _secStrgDao;
|
||||
@Inject
|
||||
protected StoragePoolWorkDao _storagePoolWorkDao;
|
||||
@Inject
|
||||
protected HypervisorGuruManager _hvGuruMgr;
|
||||
@Inject
|
||||
protected VolumeDao _volumeDao;
|
||||
@Inject
|
||||
protected OCFS2Manager _ocfs2Mgr;
|
||||
@Inject
|
||||
protected ResourceLimitService _resourceLimitMgr;
|
||||
@Inject
|
||||
protected SecondaryStorageVmManager _ssvmMgr;
|
||||
@Inject
|
||||
protected ResourceManager _resourceMgr;
|
||||
@Inject
|
||||
protected DownloadMonitor _downloadMonitor;
|
||||
@Inject
|
||||
protected ResourceTagDao _resourceTagDao;
|
||||
@Inject
|
||||
protected List<StoragePoolAllocator> _storagePoolAllocators;
|
||||
@Inject
|
||||
ConfigurationDao _configDao;
|
||||
|
|
@ -464,14 +441,19 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||
VMInstanceVO vm, final Set<StoragePool> avoid) {
|
||||
|
||||
VirtualMachineProfile<VMInstanceVO> profile = new VirtualMachineProfileImpl<VMInstanceVO>(
|
||||
vm);
|
||||
vm);
|
||||
for (StoragePoolAllocator allocator : _storagePoolAllocators) {
|
||||
final List<StoragePool> poolList = allocator.allocateToPool(
|
||||
dskCh, profile, dc.getId(), pod.getId(), clusterId, hostId,
|
||||
avoid, 1);
|
||||
if (poolList != null && !poolList.isEmpty()) {
|
||||
return (StoragePool)this.dataStoreMgr.getDataStore(poolList.get(0).getId(), DataStoreRole.Primary);
|
||||
}
|
||||
|
||||
ExcludeList avoidList = new ExcludeList();
|
||||
for(StoragePool pool : avoid){
|
||||
avoidList.addPool(pool.getId());
|
||||
}
|
||||
DataCenterDeployment plan = new DataCenterDeployment(dc.getId(), pod.getId(), clusterId, hostId, null, null);
|
||||
|
||||
final List<StoragePool> poolList = allocator.allocateToPool(dskCh, profile, plan, avoidList, 1);
|
||||
if (poolList != null && !poolList.isEmpty()) {
|
||||
return (StoragePool)this.dataStoreMgr.getDataStore(poolList.get(0).getId(), DataStoreRole.Primary);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo;
|
|||
import org.apache.cloudstack.engine.subsystem.api.storage.ScopeType;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
|
||||
|
|
@ -115,7 +116,6 @@ import com.cloud.storage.Storage.ImageFormat;
|
|||
import com.cloud.storage.Storage.StoragePoolType;
|
||||
import com.cloud.storage.Volume.Event;
|
||||
import com.cloud.storage.Volume.Type;
|
||||
import com.cloud.storage.allocator.StoragePoolAllocator;
|
||||
import com.cloud.storage.dao.DiskOfferingDao;
|
||||
import com.cloud.storage.dao.SnapshotDao;
|
||||
import com.cloud.storage.dao.SnapshotPolicyDao;
|
||||
|
|
|
|||
|
|
@ -1,209 +0,0 @@
|
|||
// 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.storage.allocator;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
|
||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.capacity.CapacityManager;
|
||||
import com.cloud.configuration.dao.ConfigurationDao;
|
||||
import com.cloud.dc.ClusterVO;
|
||||
import com.cloud.dc.dao.ClusterDao;
|
||||
import com.cloud.deploy.DataCenterDeployment;
|
||||
import com.cloud.deploy.DeploymentPlan;
|
||||
import com.cloud.deploy.DeploymentPlanner.ExcludeList;
|
||||
import com.cloud.host.Host;
|
||||
import com.cloud.server.StatsCollector;
|
||||
import com.cloud.storage.Storage.StoragePoolType;
|
||||
import com.cloud.storage.StorageManager;
|
||||
import com.cloud.storage.StoragePool;
|
||||
import com.cloud.storage.StoragePoolStatus;
|
||||
import com.cloud.storage.VMTemplateStoragePoolVO;
|
||||
import com.cloud.storage.VMTemplateStorageResourceAssoc;
|
||||
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
|
||||
import com.cloud.storage.VMTemplateVO;
|
||||
import com.cloud.storage.Volume;
|
||||
import com.cloud.storage.Volume.Type;
|
||||
import com.cloud.storage.dao.StoragePoolDao;
|
||||
import com.cloud.storage.dao.StoragePoolHostDao;
|
||||
import com.cloud.storage.dao.VMTemplateDao;
|
||||
import com.cloud.storage.dao.VMTemplateHostDao;
|
||||
import com.cloud.storage.dao.VMTemplatePoolDao;
|
||||
import com.cloud.storage.dao.VolumeDao;
|
||||
import com.cloud.storage.swift.SwiftManager;
|
||||
import com.cloud.template.TemplateManager;
|
||||
import com.cloud.utils.NumbersUtil;
|
||||
import com.cloud.utils.component.AdapterBase;
|
||||
import com.cloud.vm.DiskProfile;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.VirtualMachineProfile;
|
||||
|
||||
public abstract class AbstractStoragePoolAllocator extends AdapterBase implements StoragePoolAllocator {
|
||||
private static final Logger s_logger = Logger.getLogger(AbstractStoragePoolAllocator.class);
|
||||
@Inject TemplateManager _tmpltMgr;
|
||||
@Inject StorageManager _storageMgr;
|
||||
@Inject StoragePoolDao _storagePoolDao;
|
||||
@Inject VMTemplateHostDao _templateHostDao;
|
||||
@Inject VMTemplatePoolDao _templatePoolDao;
|
||||
@Inject VMTemplateDao _templateDao;
|
||||
@Inject VolumeDao _volumeDao;
|
||||
@Inject StoragePoolHostDao _poolHostDao;
|
||||
@Inject ConfigurationDao _configDao;
|
||||
@Inject ClusterDao _clusterDao;
|
||||
@Inject SwiftManager _swiftMgr;
|
||||
@Inject CapacityManager _capacityMgr;
|
||||
@Inject DataStoreManager dataStoreMgr;
|
||||
protected BigDecimal _storageOverprovisioningFactor = new BigDecimal(1);
|
||||
long _extraBytesPerVolume = 0;
|
||||
Random _rand;
|
||||
boolean _dontMatter;
|
||||
|
||||
@Override
|
||||
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
|
||||
super.configure(name, params);
|
||||
|
||||
Map<String, String> configs = _configDao.getConfiguration(null, params);
|
||||
|
||||
String globalStorageOverprovisioningFactor = configs.get("storage.overprovisioning.factor");
|
||||
_storageOverprovisioningFactor = new BigDecimal(NumbersUtil.parseFloat(globalStorageOverprovisioningFactor, 2.0f));
|
||||
|
||||
_extraBytesPerVolume = 0;
|
||||
|
||||
_rand = new Random(System.currentTimeMillis());
|
||||
|
||||
_dontMatter = Boolean.parseBoolean(configs.get("storage.overwrite.provisioning"));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
abstract boolean allocatorIsCorrectType(DiskProfile dskCh);
|
||||
|
||||
protected boolean templateAvailable(long templateId, long poolId) {
|
||||
VMTemplateStorageResourceAssoc thvo = _templatePoolDao.findByPoolTemplate(poolId, templateId);
|
||||
if (thvo != null) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Template id : " + templateId + " status : " + thvo.getDownloadState().toString());
|
||||
}
|
||||
return (thvo.getDownloadState()==Status.DOWNLOADED);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean localStorageAllocationNeeded(DiskProfile dskCh) {
|
||||
return dskCh.useLocalStorage();
|
||||
}
|
||||
|
||||
protected boolean poolIsCorrectType(DiskProfile dskCh, StoragePool pool) {
|
||||
boolean localStorageAllocationNeeded = localStorageAllocationNeeded(dskCh);
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Is localStorageAllocationNeeded? "+ localStorageAllocationNeeded);
|
||||
s_logger.debug("Is storage pool shared? "+ pool.isShared());
|
||||
}
|
||||
|
||||
return ((!localStorageAllocationNeeded && pool.getPoolType().isShared()) || (localStorageAllocationNeeded && !pool.getPoolType().isShared()));
|
||||
}
|
||||
|
||||
protected boolean checkPool(ExcludeList avoid, StoragePoolVO pool, DiskProfile dskCh, VMTemplateVO template, List<VMTemplateStoragePoolVO> templatesInPool,
|
||||
StatsCollector sc, DeploymentPlan plan) {
|
||||
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Checking if storage pool is suitable, name: " + pool.getName()+ " ,poolId: "+ pool.getId());
|
||||
}
|
||||
StoragePool pol = (StoragePool)this.dataStoreMgr.getPrimaryDataStore(pool.getId());
|
||||
if (avoid.shouldAvoid(pol)) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("StoragePool is in avoid set, skipping this pool");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if(dskCh.getType().equals(Type.ROOT) && pool.getPoolType().equals(StoragePoolType.Iscsi)){
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Disk needed for ROOT volume, but StoragePoolType is Iscsi, skipping this and trying other available pools");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//by default, all pools are up when successfully added
|
||||
//don't return the pool if not up (if in maintenance/prepareformaintenance/errorinmaintenance)
|
||||
if(!pool.getStatus().equals(StoragePoolStatus.Up)){
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("StoragePool status is not UP, status is: "+pool.getStatus().name()+", skipping this pool");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check that the pool type is correct
|
||||
if (!poolIsCorrectType(dskCh, pol)) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("StoragePool is not of correct type, skipping this pool");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*hypervisor type is correct*/
|
||||
// TODO : when creating a standalone volume, offering is passed as NULL, need to
|
||||
// refine the logic of checking hypervisorType based on offering info
|
||||
Long clusterId = pool.getClusterId();
|
||||
ClusterVO cluster = _clusterDao.findById(clusterId);
|
||||
if (!(cluster.getHypervisorType() == dskCh.getHypersorType())) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("StoragePool's Cluster does not have required hypervisorType, skipping this pool");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// check capacity
|
||||
Volume volume = _volumeDao.findById(dskCh.getVolumeId());
|
||||
List<Volume> requestVolumes = new ArrayList<Volume>();
|
||||
requestVolumes.add(volume);
|
||||
return _storageMgr.storagePoolHasEnoughSpace(requestVolumes, pol);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public String chooseStorageIp(VirtualMachine vm, Host host, Host storage) {
|
||||
return storage.getStorageIpAddress();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<StoragePool> allocateToPool(DiskProfile dskCh, VirtualMachineProfile<? extends VirtualMachine> vmProfile, long dcId, long podId, Long clusterId, Long hostId, Set<? extends StoragePool> avoids, int returnUpTo) {
|
||||
|
||||
ExcludeList avoid = new ExcludeList();
|
||||
for(StoragePool pool : avoids){
|
||||
avoid.addPool(pool.getId());
|
||||
}
|
||||
|
||||
DataCenterDeployment plan = new DataCenterDeployment(dcId, podId, clusterId, hostId, null, null);
|
||||
return allocateToPool(dskCh, vmProfile, plan, avoid, returnUpTo);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,175 +0,0 @@
|
|||
// 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.storage.allocator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.ejb.Local;
|
||||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.deploy.DeploymentPlan;
|
||||
import com.cloud.deploy.DeploymentPlanner.ExcludeList;
|
||||
import com.cloud.offering.ServiceOffering;
|
||||
import com.cloud.server.StatsCollector;
|
||||
import com.cloud.storage.DiskOfferingVO;
|
||||
import com.cloud.storage.VMTemplateVO;
|
||||
import com.cloud.storage.Storage.StoragePoolType;
|
||||
import com.cloud.storage.StoragePool;
|
||||
import com.cloud.storage.dao.DiskOfferingDao;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.vm.DiskProfile;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.VirtualMachineProfile;
|
||||
|
||||
@Local(value=StoragePoolAllocator.class)
|
||||
public class FirstFitStoragePoolAllocator extends AbstractStoragePoolAllocator {
|
||||
private static final Logger s_logger = Logger.getLogger(FirstFitStoragePoolAllocator.class);
|
||||
protected String _allocationAlgorithm = "random";
|
||||
|
||||
@Inject
|
||||
DiskOfferingDao _diskOfferingDao;
|
||||
|
||||
@Override
|
||||
public boolean allocatorIsCorrectType(DiskProfile dskCh) {
|
||||
return !localStorageAllocationNeeded(dskCh);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StoragePool> allocateToPool(DiskProfile dskCh, VirtualMachineProfile<? extends VirtualMachine> vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo) {
|
||||
|
||||
|
||||
VMTemplateVO template = (VMTemplateVO)vmProfile.getTemplate();
|
||||
Account account = null;
|
||||
if(vmProfile.getVirtualMachine() != null){
|
||||
account = vmProfile.getOwner();
|
||||
}
|
||||
|
||||
List<StoragePool> suitablePools = new ArrayList<StoragePool>();
|
||||
|
||||
// Check that the allocator type is correct
|
||||
if (!allocatorIsCorrectType(dskCh)) {
|
||||
return suitablePools;
|
||||
}
|
||||
long dcId = plan.getDataCenterId();
|
||||
Long podId = plan.getPodId();
|
||||
Long clusterId = plan.getClusterId();
|
||||
|
||||
if(dskCh.getTags() != null && dskCh.getTags().length != 0){
|
||||
s_logger.debug("Looking for pools in dc: " + dcId + " pod:" + podId + " cluster:" + clusterId + " having tags:" + Arrays.toString(dskCh.getTags()));
|
||||
}else{
|
||||
s_logger.debug("Looking for pools in dc: " + dcId + " pod:" + podId + " cluster:" + clusterId);
|
||||
}
|
||||
|
||||
List<StoragePoolVO> pools = _storagePoolDao.findPoolsByTags(dcId, podId, clusterId, dskCh.getTags(), null);
|
||||
if (pools.size() == 0) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
String storageType = dskCh.useLocalStorage() ? ServiceOffering.StorageType.local.toString() : ServiceOffering.StorageType.shared.toString();
|
||||
s_logger.debug("No storage pools available for " + storageType + " volume allocation, returning");
|
||||
}
|
||||
return suitablePools;
|
||||
}
|
||||
|
||||
StatsCollector sc = StatsCollector.getInstance();
|
||||
|
||||
//FixMe: We are ignoring userdispersing algorithm when account is null. Find a way to get account ID when VMprofile is null
|
||||
if(_allocationAlgorithm.equals("random") || _allocationAlgorithm.equals("userconcentratedpod_random") || (account == null)) {
|
||||
// Shuffle this so that we don't check the pools in the same order.
|
||||
Collections.shuffle(pools);
|
||||
}else if(_allocationAlgorithm.equals("userdispersing")){
|
||||
pools = reorderPoolsByNumberOfVolumes(plan, pools, account);
|
||||
}
|
||||
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("FirstFitStoragePoolAllocator has " + pools.size() + " pools to check for allocation");
|
||||
}
|
||||
|
||||
DiskOfferingVO diskOffering = _diskOfferingDao.findById(dskCh.getDiskOfferingId());
|
||||
for (StoragePoolVO pool: pools) {
|
||||
if(suitablePools.size() == returnUpTo){
|
||||
break;
|
||||
}
|
||||
if (diskOffering.getSystemUse() && pool.getPoolType() == StoragePoolType.RBD) {
|
||||
s_logger.debug("Skipping RBD pool " + pool.getName() + " as a suitable pool. RBD is not supported for System VM's");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (checkPool(avoid, pool, dskCh, template, null, sc, plan)) {
|
||||
StoragePool pol = (StoragePool)this.dataStoreMgr.getPrimaryDataStore(pool.getId());
|
||||
suitablePools.add(pol);
|
||||
}
|
||||
}
|
||||
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("FirstFitStoragePoolAllocator returning "+suitablePools.size() +" suitable storage pools");
|
||||
}
|
||||
|
||||
return suitablePools;
|
||||
}
|
||||
|
||||
private List<StoragePoolVO> reorderPoolsByNumberOfVolumes(DeploymentPlan plan, List<StoragePoolVO> pools, Account account) {
|
||||
if(account == null){
|
||||
return pools;
|
||||
}
|
||||
long dcId = plan.getDataCenterId();
|
||||
Long podId = plan.getPodId();
|
||||
Long clusterId = plan.getClusterId();
|
||||
|
||||
List<Long> poolIdsByVolCount = _volumeDao.listPoolIdsByVolumeCount(dcId, podId, clusterId, account.getAccountId());
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("List of pools in ascending order of number of volumes for account id: "+ account.getAccountId() + " is: "+ poolIdsByVolCount);
|
||||
}
|
||||
|
||||
//now filter the given list of Pools by this ordered list
|
||||
Map<Long, StoragePoolVO> poolMap = new HashMap<Long, StoragePoolVO>();
|
||||
for (StoragePoolVO pool : pools) {
|
||||
poolMap.put(pool.getId(), pool);
|
||||
}
|
||||
List<Long> matchingPoolIds = new ArrayList<Long>(poolMap.keySet());
|
||||
|
||||
poolIdsByVolCount.retainAll(matchingPoolIds);
|
||||
|
||||
List<StoragePoolVO> reorderedPools = new ArrayList<StoragePoolVO>();
|
||||
for(Long id: poolIdsByVolCount){
|
||||
reorderedPools.add(poolMap.get(id));
|
||||
}
|
||||
|
||||
return reorderedPools;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
|
||||
super.configure(name, params);
|
||||
|
||||
if (_configDao != null) {
|
||||
Map<String, String> configs = _configDao.getConfiguration(params);
|
||||
String allocationAlgorithm = configs.get("vm.allocation.algorithm");
|
||||
if (allocationAlgorithm != null) {
|
||||
_allocationAlgorithm = allocationAlgorithm;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,288 +0,0 @@
|
|||
// 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.storage.allocator;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.ejb.Local;
|
||||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.capacity.CapacityVO;
|
||||
import com.cloud.capacity.dao.CapacityDao;
|
||||
import com.cloud.configuration.dao.ConfigurationDao;
|
||||
import com.cloud.deploy.DeploymentPlan;
|
||||
import com.cloud.deploy.DeploymentPlanner.ExcludeList;
|
||||
import com.cloud.offering.ServiceOffering;
|
||||
import com.cloud.service.dao.ServiceOfferingDao;
|
||||
import com.cloud.storage.StoragePool;
|
||||
import com.cloud.storage.StoragePoolHostVO;
|
||||
import com.cloud.storage.Volume;
|
||||
import com.cloud.storage.VolumeVO;
|
||||
import com.cloud.storage.dao.StoragePoolHostDao;
|
||||
import com.cloud.utils.DateUtil;
|
||||
import com.cloud.utils.NumbersUtil;
|
||||
import com.cloud.utils.db.GenericSearchBuilder;
|
||||
import com.cloud.utils.db.JoinBuilder;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.utils.db.SearchCriteria.Func;
|
||||
import com.cloud.vm.DiskProfile;
|
||||
import com.cloud.vm.UserVmVO;
|
||||
import com.cloud.vm.VMInstanceVO;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.VirtualMachine.State;
|
||||
import com.cloud.vm.VirtualMachineProfile;
|
||||
import com.cloud.vm.dao.UserVmDao;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
|
||||
//
|
||||
// TODO
|
||||
// Rush to make LocalStoragePoolAllocator use static allocation status, we should revisit the overall
|
||||
// allocation process to make it more reliable in next release. The code put in here is pretty ugly
|
||||
//
|
||||
@Local(value = StoragePoolAllocator.class)
|
||||
public class LocalStoragePoolAllocator extends FirstFitStoragePoolAllocator {
|
||||
private static final Logger s_logger = Logger.getLogger(LocalStoragePoolAllocator.class);
|
||||
|
||||
@Inject
|
||||
StoragePoolHostDao _poolHostDao;
|
||||
@Inject
|
||||
VMInstanceDao _vmInstanceDao;
|
||||
@Inject
|
||||
UserVmDao _vmDao;
|
||||
@Inject
|
||||
ServiceOfferingDao _offeringDao;
|
||||
@Inject
|
||||
CapacityDao _capacityDao;
|
||||
@Inject
|
||||
ConfigurationDao _configDao;
|
||||
|
||||
protected GenericSearchBuilder<VMInstanceVO, Long> VmsOnPoolSearch;
|
||||
|
||||
private int _secondsToSkipStoppedVMs = 86400;
|
||||
|
||||
@Override
|
||||
public boolean allocatorIsCorrectType(DiskProfile dskCh) {
|
||||
return localStorageAllocationNeeded(dskCh);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StoragePool> allocateToPool(DiskProfile dskCh, VirtualMachineProfile<? extends VirtualMachine> vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo) {
|
||||
|
||||
List<StoragePool> suitablePools = new ArrayList<StoragePool>();
|
||||
|
||||
// Check that the allocator type is correct
|
||||
if (!allocatorIsCorrectType(dskCh)) {
|
||||
return suitablePools;
|
||||
}
|
||||
|
||||
ExcludeList myAvoids = new ExcludeList(avoid.getDataCentersToAvoid(), avoid.getPodsToAvoid(), avoid.getClustersToAvoid(), avoid.getHostsToAvoid(), avoid.getPoolsToAvoid());
|
||||
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("LocalStoragePoolAllocator trying to find storage pool to fit the vm");
|
||||
}
|
||||
|
||||
// data disk and host identified from deploying vm (attach volume case)
|
||||
if (dskCh.getType() == Volume.Type.DATADISK && plan.getHostId() != null) {
|
||||
List<StoragePoolHostVO> hostPools = _poolHostDao.listByHostId(plan.getHostId());
|
||||
for (StoragePoolHostVO hostPool: hostPools) {
|
||||
StoragePoolVO pool = _storagePoolDao.findById(hostPool.getPoolId());
|
||||
if (pool != null && pool.isLocal()) {
|
||||
s_logger.debug("Found suitable local storage pool " + pool.getId() + ", adding to list");
|
||||
StoragePool pol = (StoragePool)this.dataStoreMgr.getPrimaryDataStore(pool.getId());
|
||||
suitablePools.add(pol);
|
||||
}
|
||||
|
||||
if (suitablePools.size() == returnUpTo) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
List<StoragePool> availablePool;
|
||||
while (!(availablePool = super.allocateToPool(dskCh, vmProfile, plan, myAvoids, 1)).isEmpty()) {
|
||||
StoragePool pool = availablePool.get(0);
|
||||
myAvoids.addPool(pool.getId());
|
||||
List<StoragePoolHostVO> hostsInSPool = _poolHostDao.listByPoolId(pool.getId());
|
||||
assert (hostsInSPool.size() == 1) : "Local storage pool should be one host per pool";
|
||||
|
||||
s_logger.debug("Found suitable local storage pool " + pool.getId() + ", adding to list");
|
||||
suitablePools.add(pool);
|
||||
|
||||
if (suitablePools.size() == returnUpTo) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("LocalStoragePoolAllocator returning " + suitablePools.size() + " suitable storage pools");
|
||||
}
|
||||
|
||||
if (suitablePools.isEmpty()) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Unable to find storage pool to fit the vm");
|
||||
}
|
||||
}
|
||||
return suitablePools;
|
||||
}
|
||||
|
||||
// we don't need to check host capacity now, since hostAllocators will do that anyway
|
||||
private boolean hostHasCpuMemoryCapacity(long hostId, List<Long> vmOnHost, VMInstanceVO vm) {
|
||||
|
||||
ServiceOffering so = _offeringDao.findById(vm.getServiceOfferingId());
|
||||
|
||||
long usedMemory = calcHostAllocatedCpuMemoryCapacity(vmOnHost, CapacityVO.CAPACITY_TYPE_MEMORY);
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Calculated static-allocated memory for VMs on host " + hostId + ": " + usedMemory + " bytes, requesting memory: " + (so != null ? so.getRamSize() * 1024L * 1024L : "")
|
||||
+ " bytes");
|
||||
}
|
||||
|
||||
SearchCriteria<CapacityVO> sc = _capacityDao.createSearchCriteria();
|
||||
sc.addAnd("hostOrPoolId", SearchCriteria.Op.EQ, hostId);
|
||||
sc.addAnd("capacityType", SearchCriteria.Op.EQ, CapacityVO.CAPACITY_TYPE_MEMORY);
|
||||
List<CapacityVO> capacities = _capacityDao.search(sc, null);
|
||||
if (capacities.size() > 0) {
|
||||
if (capacities.get(0).getTotalCapacity() < usedMemory + (so != null ? so.getRamSize() * 1024L * 1024L : 0)) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Host " + hostId + " runs out of memory capacity");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
s_logger.warn("Host " + hostId + " has not reported memory capacity yet");
|
||||
return false;
|
||||
}
|
||||
|
||||
long usedCpu = calcHostAllocatedCpuMemoryCapacity(vmOnHost, CapacityVO.CAPACITY_TYPE_CPU);
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Calculated static-allocated CPU for VMs on host " + hostId + ": " + usedCpu + " GHz, requesting cpu: " + (so != null ? so.getCpu() * so.getSpeed() : "") + " GHz");
|
||||
}
|
||||
|
||||
sc = _capacityDao.createSearchCriteria();
|
||||
sc.addAnd("hostOrPoolId", SearchCriteria.Op.EQ, hostId);
|
||||
sc.addAnd("capacityType", SearchCriteria.Op.EQ, CapacityVO.CAPACITY_TYPE_CPU);
|
||||
capacities = _capacityDao.search(sc, null);
|
||||
if (capacities.size() > 0) {
|
||||
if (capacities.get(0).getTotalCapacity() < usedCpu + (so != null ? so.getCpu() * so.getSpeed() : 0)) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Host " + hostId + " runs out of CPU capacity");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
s_logger.warn("Host " + hostId + " has not reported CPU capacity yet");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean skipCalculation(VMInstanceVO vm) {
|
||||
if (vm == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (vm.getState() == State.Expunging) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Skip counting capacity for Expunging VM : " + vm.getInstanceName());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (vm.getState() == State.Destroyed && vm.getType() != VirtualMachine.Type.User) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (vm.getState() == State.Stopped || vm.getState() == State.Destroyed) {
|
||||
// for stopped/Destroyed VMs, we will skip counting it if it hasn't been used for a while
|
||||
|
||||
long millisecondsSinceLastUpdate = DateUtil.currentGMTTime().getTime() - vm.getUpdateTime().getTime();
|
||||
if (millisecondsSinceLastUpdate > _secondsToSkipStoppedVMs * 1000L) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Skip counting vm " + vm.getInstanceName() + " in capacity allocation as it has been stopped for " + millisecondsSinceLastUpdate / 60000 + " minutes");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private long calcHostAllocatedCpuMemoryCapacity(List<Long> vmOnHost, short capacityType) {
|
||||
assert (capacityType == CapacityVO.CAPACITY_TYPE_MEMORY || capacityType == CapacityVO.CAPACITY_TYPE_CPU) : "Invalid capacity type passed in calcHostAllocatedCpuCapacity()";
|
||||
|
||||
long usedCapacity = 0;
|
||||
for (Long vmId : vmOnHost) {
|
||||
VMInstanceVO vm = _vmInstanceDao.findById(vmId);
|
||||
if (skipCalculation(vm)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ServiceOffering so = _offeringDao.findById(vm.getServiceOfferingId());
|
||||
if (vm.getType() == VirtualMachine.Type.User) {
|
||||
UserVmVO userVm = _vmDao.findById(vm.getId());
|
||||
if (userVm == null) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (capacityType == CapacityVO.CAPACITY_TYPE_MEMORY) {
|
||||
usedCapacity += so.getRamSize() * 1024L * 1024L;
|
||||
} else if (capacityType == CapacityVO.CAPACITY_TYPE_CPU) {
|
||||
usedCapacity += so.getCpu() * so.getSpeed();
|
||||
}
|
||||
}
|
||||
|
||||
return usedCapacity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
|
||||
super.configure(name, params);
|
||||
|
||||
_storageOverprovisioningFactor = new BigDecimal(1);
|
||||
_extraBytesPerVolume = NumbersUtil.parseLong((String) params.get("extra.bytes.per.volume"), 50 * 1024L * 1024L);
|
||||
|
||||
Map<String, String> configs = _configDao.getConfiguration("management-server", params);
|
||||
String value = configs.get("vm.resource.release.interval");
|
||||
_secondsToSkipStoppedVMs = NumbersUtil.parseInt(value, 86400);
|
||||
|
||||
VmsOnPoolSearch = _vmInstanceDao.createSearchBuilder(Long.class);
|
||||
VmsOnPoolSearch.select(null, Func.DISTINCT, VmsOnPoolSearch.entity().getId());
|
||||
VmsOnPoolSearch.and("removed", VmsOnPoolSearch.entity().getRemoved(), SearchCriteria.Op.NULL);
|
||||
VmsOnPoolSearch.and("state", VmsOnPoolSearch.entity().getState(), SearchCriteria.Op.NIN);
|
||||
|
||||
SearchBuilder<VolumeVO> sbVolume = _volumeDao.createSearchBuilder();
|
||||
sbVolume.and("poolId", sbVolume.entity().getPoolId(), SearchCriteria.Op.EQ);
|
||||
|
||||
VmsOnPoolSearch.join("volumeJoin", sbVolume, VmsOnPoolSearch.entity().getId(), sbVolume.entity().getInstanceId(), JoinBuilder.JoinType.INNER);
|
||||
|
||||
sbVolume.done();
|
||||
VmsOnPoolSearch.done();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public LocalStoragePoolAllocator() {
|
||||
}
|
||||
}
|
||||
|
|
@ -20,6 +20,7 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.ScopeType;
|
||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
||||
|
||||
import com.cloud.storage.StoragePoolStatus;
|
||||
|
|
@ -37,7 +38,7 @@ public interface StoragePoolDao extends GenericDao<StoragePoolVO, Long> {
|
|||
/**
|
||||
* @param datacenterId -- the id of the datacenter (availability zone)
|
||||
*/
|
||||
List<StoragePoolVO> listBy(long datacenterId, long podId, Long clusterId);
|
||||
List<StoragePoolVO> listBy(long datacenterId, long podId, Long clusterId, ScopeType scope);
|
||||
|
||||
/**
|
||||
* Set capacity of storage pool in bytes
|
||||
|
|
@ -71,9 +72,9 @@ public interface StoragePoolDao extends GenericDao<StoragePoolVO, Long> {
|
|||
* @param details details to match. All must match for the pool to be returned.
|
||||
* @return List of StoragePoolVO
|
||||
*/
|
||||
List<StoragePoolVO> findPoolsByDetails(long dcId, long podId, Long clusterId, Map<String, String> details);
|
||||
List<StoragePoolVO> findPoolsByDetails(long dcId, long podId, Long clusterId, Map<String, String> details, ScopeType scope);
|
||||
|
||||
List<StoragePoolVO> findPoolsByTags(long dcId, long podId, Long clusterId, String[] tags, Boolean shared);
|
||||
List<StoragePoolVO> findPoolsByTags(long dcId, long podId, Long clusterId, String[] tags);
|
||||
|
||||
/**
|
||||
* Find pool by UUID.
|
||||
|
|
@ -104,4 +105,9 @@ public interface StoragePoolDao extends GenericDao<StoragePoolVO, Long> {
|
|||
List<StoragePoolVO> listByStatusInZone(long dcId, StoragePoolStatus status);
|
||||
|
||||
List<StoragePoolVO> listPoolsByCluster(long clusterId);
|
||||
|
||||
List<StoragePoolVO> findLocalStoragePoolsByTags(long dcId, long podId,
|
||||
Long clusterId, String[] tags);
|
||||
|
||||
List<StoragePoolVO> findZoneWideStoragePoolsByTags(long dcId, String[] tags);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,14 +28,13 @@ import javax.ejb.Local;
|
|||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.ScopeType;
|
||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.cloud.host.Status;
|
||||
import com.cloud.storage.Storage.StoragePoolType;
|
||||
import com.cloud.storage.StoragePoolDetailVO;
|
||||
import com.cloud.storage.StoragePoolStatus;
|
||||
|
||||
import com.cloud.utils.db.DB;
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.db.GenericSearchBuilder;
|
||||
|
|
@ -43,6 +42,8 @@ import com.cloud.utils.db.SearchBuilder;
|
|||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.utils.db.SearchCriteria.Func;
|
||||
import com.cloud.utils.db.SearchCriteria.Op;
|
||||
import com.cloud.utils.db.SearchCriteria2;
|
||||
import com.cloud.utils.db.SearchCriteriaService;
|
||||
import com.cloud.utils.db.Transaction;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
|
||||
|
|
@ -59,8 +60,11 @@ public class StoragePoolDaoImpl extends GenericDaoBase<StoragePoolVO, Long> imp
|
|||
|
||||
@Inject protected StoragePoolDetailsDao _detailsDao;
|
||||
|
||||
private final String DetailsSqlPrefix = "SELECT storage_pool.* from storage_pool LEFT JOIN storage_pool_details ON storage_pool.id = storage_pool_details.pool_id WHERE storage_pool.removed is null and storage_pool.data_center_id = ? and (storage_pool.pod_id = ? or storage_pool.pod_id is null) and (";
|
||||
private final String DetailsSqlPrefix = "SELECT storage_pool.* from storage_pool LEFT JOIN storage_pool_details ON storage_pool.id = storage_pool_details.pool_id WHERE storage_pool.removed is null and storage_pool.status = 'Up' and storage_pool.data_center_id = ? and (storage_pool.pod_id = ? or storage_pool.pod_id is null) and storage_pool.scope = ? and (";
|
||||
private final String DetailsSqlSuffix = ") GROUP BY storage_pool_details.pool_id HAVING COUNT(storage_pool_details.name) >= ?";
|
||||
private final String ZoneWideDetailsSqlPrefix = "SELECT storage_pool.* from storage_pool LEFT JOIN storage_pool_details ON storage_pool.id = storage_pool_details.pool_id WHERE storage_pool.removed is null and storage_pool.status = 'Up' and storage_pool.data_center_id = ? and storage_pool.scope = ? and (";
|
||||
private final String ZoneWideDetailsSqlSuffix = ") GROUP BY storage_pool_details.pool_id HAVING COUNT(storage_pool_details.name) >= ?";
|
||||
|
||||
private final String FindPoolTagDetails = "SELECT storage_pool_details.name FROM storage_pool_details WHERE pool_id = ? and value = ?";
|
||||
|
||||
protected StoragePoolDaoImpl() {
|
||||
|
|
@ -77,6 +81,8 @@ public class StoragePoolDaoImpl extends GenericDaoBase<StoragePoolVO, Long> imp
|
|||
|
||||
DcPodSearch = createSearchBuilder();
|
||||
DcPodSearch.and("datacenterId", DcPodSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
|
||||
DcPodSearch.and("status", DcPodSearch.entity().getStatus(), SearchCriteria.Op.EQ);
|
||||
DcPodSearch.and("scope", DcPodSearch.entity().getScope(), SearchCriteria.Op.EQ);
|
||||
DcPodSearch.and().op("nullpod", DcPodSearch.entity().getPodId(), SearchCriteria.Op.NULL);
|
||||
DcPodSearch.or("podId", DcPodSearch.entity().getPodId(), SearchCriteria.Op.EQ);
|
||||
DcPodSearch.cp();
|
||||
|
|
@ -87,6 +93,8 @@ public class StoragePoolDaoImpl extends GenericDaoBase<StoragePoolVO, Long> imp
|
|||
|
||||
DcPodAnyClusterSearch = createSearchBuilder();
|
||||
DcPodAnyClusterSearch.and("datacenterId", DcPodAnyClusterSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
|
||||
DcPodAnyClusterSearch.and("status", DcPodAnyClusterSearch.entity().getStatus(), SearchCriteria.Op.EQ);
|
||||
DcPodAnyClusterSearch.and("scope", DcPodAnyClusterSearch.entity().getScope(), SearchCriteria.Op.EQ);
|
||||
DcPodAnyClusterSearch.and().op("nullpod", DcPodAnyClusterSearch.entity().getPodId(), SearchCriteria.Op.NULL);
|
||||
DcPodAnyClusterSearch.or("podId", DcPodAnyClusterSearch.entity().getPodId(), SearchCriteria.Op.EQ);
|
||||
DcPodAnyClusterSearch.cp();
|
||||
|
|
@ -192,11 +200,13 @@ public class StoragePoolDaoImpl extends GenericDaoBase<StoragePoolVO, Long> imp
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<StoragePoolVO> listBy(long datacenterId, long podId, Long clusterId) {
|
||||
public List<StoragePoolVO> listBy(long datacenterId, long podId, Long clusterId, ScopeType scope) {
|
||||
if (clusterId != null) {
|
||||
SearchCriteria<StoragePoolVO> sc = DcPodSearch.create();
|
||||
sc.setParameters("datacenterId", datacenterId);
|
||||
sc.setParameters("podId", podId);
|
||||
sc.setParameters("status", Status.Up);
|
||||
sc.setParameters("scope", scope);
|
||||
|
||||
sc.setParameters("cluster", clusterId);
|
||||
return listBy(sc);
|
||||
|
|
@ -204,6 +214,8 @@ public class StoragePoolDaoImpl extends GenericDaoBase<StoragePoolVO, Long> imp
|
|||
SearchCriteria<StoragePoolVO> sc = DcPodAnyClusterSearch.create();
|
||||
sc.setParameters("datacenterId", datacenterId);
|
||||
sc.setParameters("podId", podId);
|
||||
sc.setParameters("status", Status.Up);
|
||||
sc.setParameters("scope", scope);
|
||||
return listBy(sc);
|
||||
}
|
||||
}
|
||||
|
|
@ -242,11 +254,12 @@ public class StoragePoolDaoImpl extends GenericDaoBase<StoragePoolVO, Long> imp
|
|||
|
||||
@DB
|
||||
@Override
|
||||
public List<StoragePoolVO> findPoolsByDetails(long dcId, long podId, Long clusterId, Map<String, String> details) {
|
||||
public List<StoragePoolVO> findPoolsByDetails(long dcId, long podId, Long clusterId, Map<String, String> details, ScopeType scope) {
|
||||
StringBuilder sql = new StringBuilder(DetailsSqlPrefix);
|
||||
if (clusterId != null) {
|
||||
sql.append("storage_pool.cluster_id = ? OR storage_pool.cluster_id IS NULL) AND (");
|
||||
}
|
||||
|
||||
for (Map.Entry<String, String> detail : details.entrySet()) {
|
||||
sql.append("((storage_pool_details.name='").append(detail.getKey()).append("') AND (storage_pool_details.value='").append(detail.getValue()).append("')) OR ");
|
||||
}
|
||||
|
|
@ -259,6 +272,7 @@ public class StoragePoolDaoImpl extends GenericDaoBase<StoragePoolVO, Long> imp
|
|||
int i = 1;
|
||||
pstmt.setLong(i++, dcId);
|
||||
pstmt.setLong(i++, podId);
|
||||
pstmt.setString(i++, scope.toString());
|
||||
if (clusterId != null) {
|
||||
pstmt.setLong(i++, clusterId);
|
||||
}
|
||||
|
|
@ -283,26 +297,67 @@ public class StoragePoolDaoImpl extends GenericDaoBase<StoragePoolVO, Long> imp
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<StoragePoolVO> findPoolsByTags(long dcId, long podId, Long clusterId, String[] tags, Boolean shared) {
|
||||
public List<StoragePoolVO> findPoolsByTags(long dcId, long podId, Long clusterId, String[] tags) {
|
||||
List<StoragePoolVO> storagePools = null;
|
||||
if (tags == null || tags.length == 0) {
|
||||
storagePools = listBy(dcId, podId, clusterId);
|
||||
storagePools = listBy(dcId, podId, clusterId, ScopeType.CLUSTER);
|
||||
} else {
|
||||
Map<String, String> details = tagsToDetails(tags);
|
||||
storagePools = findPoolsByDetails(dcId, podId, clusterId, details);
|
||||
storagePools = findPoolsByDetails(dcId, podId, clusterId, details, ScopeType.CLUSTER);
|
||||
}
|
||||
|
||||
if (shared == null) {
|
||||
return storagePools;
|
||||
|
||||
return storagePools;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StoragePoolVO> findLocalStoragePoolsByTags(long dcId, long podId, Long clusterId, String[] tags) {
|
||||
List<StoragePoolVO> storagePools = null;
|
||||
if (tags == null || tags.length == 0) {
|
||||
storagePools = listBy(dcId, podId, clusterId, ScopeType.HOST);
|
||||
} else {
|
||||
List<StoragePoolVO> filteredStoragePools = new ArrayList<StoragePoolVO>(storagePools);
|
||||
for (StoragePoolVO pool : storagePools) {
|
||||
if (shared != pool.isShared()) {
|
||||
filteredStoragePools.remove(pool);
|
||||
}
|
||||
}
|
||||
|
||||
return filteredStoragePools;
|
||||
Map<String, String> details = tagsToDetails(tags);
|
||||
storagePools = findPoolsByDetails(dcId, podId, clusterId, details, ScopeType.HOST);
|
||||
}
|
||||
|
||||
return storagePools;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StoragePoolVO> findZoneWideStoragePoolsByTags(long dcId, String[] tags) {
|
||||
List<StoragePoolVO> storagePools = null;
|
||||
if (tags == null || tags.length == 0) {
|
||||
SearchCriteriaService<StoragePoolVO, StoragePoolVO> sc = SearchCriteria2.create(StoragePoolVO.class);
|
||||
sc.addAnd(sc.getEntity().getDataCenterId(), Op.EQ, dcId);
|
||||
sc.addAnd(sc.getEntity().getStatus(), Op.EQ, Status.Up);
|
||||
sc.addAnd(sc.getEntity().getScope(), Op.EQ, ScopeType.ZONE);
|
||||
return sc.list();
|
||||
} else {
|
||||
Map<String, String> details = tagsToDetails(tags);
|
||||
|
||||
StringBuilder sql = new StringBuilder(ZoneWideDetailsSqlPrefix);
|
||||
|
||||
for (Map.Entry<String, String> detail : details.entrySet()) {
|
||||
sql.append("((storage_pool_details.name='").append(detail.getKey()).append("') AND (storage_pool_details.value='").append(detail.getValue()).append("')) OR ");
|
||||
}
|
||||
sql.delete(sql.length() - 4, sql.length());
|
||||
sql.append(ZoneWideDetailsSqlSuffix);
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
PreparedStatement pstmt = null;
|
||||
try {
|
||||
pstmt = txn.prepareAutoCloseStatement(sql.toString());
|
||||
int i = 1;
|
||||
pstmt.setLong(i++, dcId);
|
||||
pstmt.setString(i++, ScopeType.ZONE.toString());
|
||||
pstmt.setInt(i++, details.size());
|
||||
ResultSet rs = pstmt.executeQuery();
|
||||
List<StoragePoolVO> pools = new ArrayList<StoragePoolVO>();
|
||||
while (rs.next()) {
|
||||
pools.add(toEntityBean(rs, false));
|
||||
}
|
||||
return pools;
|
||||
} catch (SQLException e) {
|
||||
throw new CloudRuntimeException("Unable to execute " + pstmt, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -97,8 +97,8 @@ public class Transaction {
|
|||
/* FIXME: We need a better solution for this
|
||||
* Initialize encryption if we need it for db.properties
|
||||
*/
|
||||
EncryptionSecretKeyChecker enc = new EncryptionSecretKeyChecker();
|
||||
enc.check();
|
||||
/*EncryptionSecretKeyChecker enc = new EncryptionSecretKeyChecker();
|
||||
enc.check(); */
|
||||
}
|
||||
|
||||
private final LinkedList<StackElement> _stack;
|
||||
|
|
|
|||
|
|
@ -20,10 +20,13 @@ import java.lang.reflect.Method;
|
|||
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.Signature;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
|
||||
public class TransactionContextBuilder implements MethodInterceptor {
|
||||
private static final Logger s_logger = Logger.getLogger(TransactionContextBuilder.class);
|
||||
public TransactionContextBuilder() {
|
||||
}
|
||||
|
||||
|
|
@ -31,7 +34,15 @@ public class TransactionContextBuilder implements MethodInterceptor {
|
|||
MethodSignature methodSignature = (MethodSignature)call.getSignature();
|
||||
Method targetMethod = methodSignature.getMethod();
|
||||
if(needToIntercept(targetMethod)) {
|
||||
Transaction txn = Transaction.open(call.getSignature().getName());
|
||||
Transaction txn = null;
|
||||
try {
|
||||
Signature s = call.getSignature();
|
||||
String name = s.getName();
|
||||
txn = Transaction.open(name);
|
||||
} catch (Throwable e) {
|
||||
s_logger.debug("Failed to open transaction: " + e.toString());
|
||||
throw e;
|
||||
}
|
||||
Object ret = null;
|
||||
try {
|
||||
ret = call.proceed();
|
||||
|
|
|
|||
Loading…
Reference in New Issue