CLOUDSTACK-724: add basic zone wide storage support, refactor storage allocator, need ui support

This commit is contained in:
Edison Su 2013-02-26 18:39:12 -08:00
parent 3902f505ee
commit 8e360f342d
38 changed files with 1363 additions and 1089 deletions

View File

@ -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"/>

View File

@ -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>

View File

@ -311,4 +311,8 @@ public class DiskOfferingVO implements DiskOffering {
public int getSortKey() {
return sortKey;
}
public void setRecreatable(boolean recreatable) {
this.recreatable = recreatable;
}
}

View File

@ -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
*

View File

@ -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>

View File

@ -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;
}
}
}

View File

@ -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);
}
}
}

View File

@ -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);
}*/
}

View File

@ -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();
}
}

View File

@ -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>

View File

@ -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>

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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() {
}
}

View File

@ -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() {
}
}

View File

@ -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;
}
}

View File

@ -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(

View File

@ -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;

View File

@ -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");

View File

@ -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);

View File

@ -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>

View File

@ -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;
}
}

View File

@ -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>

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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();

View File

@ -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;
}

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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() {
}
}

View File

@ -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);
}

View File

@ -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);
}
}
}

View File

@ -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;

View File

@ -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();