Skip to content

Commit 33dc746

Browse files
committed
Merge remote-tracking branch 'origin/4.19'
2 parents f76c6f3 + fe5d741 commit 33dc746

File tree

52 files changed

+1785
-601
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+1785
-601
lines changed

api/src/main/java/com/cloud/offering/ServiceOffering.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ enum StorageType {
102102

103103
boolean getDefaultUse();
104104

105-
String getSystemVmType();
105+
String getVmType();
106106

107107
String getDeploymentPlanner();
108108

api/src/main/java/org/apache/cloudstack/acl/RoleService.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,9 @@ public interface RoleService {
3838
* Moreover, we will check if the requested role is of 'Admin' type; roles with 'Admin' type should only be visible to 'root admins'.
3939
* Therefore, if a non-'root admin' user tries to search for an 'Admin' role, this method will return null.
4040
*/
41-
Role findRole(Long id, boolean removePrivateRoles);
41+
Role findRole(Long id, boolean ignorePrivateRoles);
42+
43+
List<Role> findRoles(List<Long> ids, boolean ignorePrivateRoles);
4244

4345
Role findRole(Long id);
4446

api/src/main/java/org/apache/cloudstack/api/InternalIdentity.java

+14
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,18 @@
2525

2626
public interface InternalIdentity extends Serializable {
2727
long getId();
28+
29+
/*
30+
Helper method to add conditions in joins where some column name is equal to a string value
31+
*/
32+
default Object setString(String str) {
33+
return null;
34+
}
35+
36+
/*
37+
Helper method to add conditions in joins where some column name is equal to a long value
38+
*/
39+
default Object setLong(Long l) {
40+
return null;
41+
}
2842
}

engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreDriver.java

+15
Original file line numberDiff line numberDiff line change
@@ -142,4 +142,19 @@ default boolean requiresAccessForMigration(DataObject dataObject) {
142142
boolean isStorageSupportHA(StoragePoolType type);
143143

144144
void detachVolumeFromAllStorageNodes(Volume volume);
145+
/**
146+
* Data store driver needs its grantAccess() method called for volumes in order for them to be used with a host.
147+
* @return true if we should call grantAccess() to use a volume
148+
*/
149+
default boolean volumesRequireGrantAccessWhenUsed() {
150+
return false;
151+
}
152+
153+
/**
154+
* Zone-wide data store supports using a volume across clusters without the need for data motion
155+
* @return true if we don't need to data motion volumes across clusters for zone-wide use
156+
*/
157+
default boolean zoneWideVolumesAvailableWithoutClusterMotion() {
158+
return false;
159+
}
145160
}

engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java

+22-20
Original file line numberDiff line numberDiff line change
@@ -1858,6 +1858,18 @@ private VolumeVO setPassphraseForVolumeEncryption(VolumeVO volume) {
18581858
return _volsDao.persist(volume);
18591859
}
18601860

1861+
protected void grantVolumeAccessToHostIfNeeded(PrimaryDataStore volumeStore, long volumeId, Host host, String volToString) {
1862+
PrimaryDataStoreDriver driver = (PrimaryDataStoreDriver)volumeStore.getDriver();
1863+
if (!driver.volumesRequireGrantAccessWhenUsed()) {
1864+
return;
1865+
}
1866+
try {
1867+
volService.grantAccess(volFactory.getVolume(volumeId), host, volumeStore);
1868+
} catch (Exception e) {
1869+
throw new StorageAccessException(String.format("Unable to grant access to volume [%s] on host [%s].", volToString, host));
1870+
}
1871+
}
1872+
18611873
@Override
18621874
public void prepare(VirtualMachineProfile vm, DeployDestination dest) throws StorageUnavailableException, InsufficientStorageCapacityException, ConcurrentOperationException, StorageAccessException {
18631875
if (dest == null) {
@@ -1875,18 +1887,18 @@ public void prepare(VirtualMachineProfile vm, DeployDestination dest) throws Sto
18751887

18761888
List<VolumeTask> tasks = getTasks(vols, dest.getStorageForDisks(), vm);
18771889
Volume vol = null;
1878-
StoragePool pool;
1890+
PrimaryDataStore store;
18791891
for (VolumeTask task : tasks) {
18801892
if (task.type == VolumeTaskType.NOP) {
18811893
vol = task.volume;
18821894

18831895
String volToString = getReflectOnlySelectedFields(vol);
18841896

1885-
pool = (StoragePool)dataStoreMgr.getDataStore(task.pool.getId(), DataStoreRole.Primary);
1897+
store = (PrimaryDataStore)dataStoreMgr.getDataStore(task.pool.getId(), DataStoreRole.Primary);
18861898

18871899
// For zone-wide managed storage, it is possible that the VM can be started in another
18881900
// cluster. In that case, make sure that the volume is in the right access group.
1889-
if (pool.isManaged()) {
1901+
if (store.isManaged()) {
18901902
Host lastHost = _hostDao.findById(vm.getVirtualMachine().getLastHostId());
18911903
Host host = _hostDao.findById(vm.getVirtualMachine().getHostId());
18921904

@@ -1895,37 +1907,27 @@ public void prepare(VirtualMachineProfile vm, DeployDestination dest) throws Sto
18951907

18961908
if (lastClusterId != clusterId) {
18971909
if (lastHost != null) {
1898-
storageMgr.removeStoragePoolFromCluster(lastHost.getId(), vol.get_iScsiName(), pool);
1899-
1900-
DataStore storagePool = dataStoreMgr.getDataStore(pool.getId(), DataStoreRole.Primary);
1901-
1902-
volService.revokeAccess(volFactory.getVolume(vol.getId()), lastHost, storagePool);
1910+
storageMgr.removeStoragePoolFromCluster(lastHost.getId(), vol.get_iScsiName(), store);
1911+
volService.revokeAccess(volFactory.getVolume(vol.getId()), lastHost, store);
19031912
}
19041913

19051914
try {
1906-
volService.grantAccess(volFactory.getVolume(vol.getId()), host, (DataStore)pool);
1915+
volService.grantAccess(volFactory.getVolume(vol.getId()), host, store);
19071916
} catch (Exception e) {
19081917
throw new StorageAccessException(String.format("Unable to grant access to volume [%s] on host [%s].", volToString, host));
19091918
}
19101919
} else {
1911-
// This might impact other managed storages, grant access for PowerFlex and Iscsi/Solidfire storage pool only
1912-
if (pool.getPoolType() == Storage.StoragePoolType.PowerFlex || pool.getPoolType() == Storage.StoragePoolType.Iscsi) {
1913-
try {
1914-
volService.grantAccess(volFactory.getVolume(vol.getId()), host, (DataStore)pool);
1915-
} catch (Exception e) {
1916-
throw new StorageAccessException(String.format("Unable to grant access to volume [%s] on host [%s].", volToString, host));
1917-
}
1918-
}
1920+
grantVolumeAccessToHostIfNeeded(store, vol.getId(), host, volToString);
19191921
}
19201922
} else {
19211923
handleCheckAndRepairVolume(vol, vm.getVirtualMachine().getHostId());
19221924
}
19231925
} else if (task.type == VolumeTaskType.MIGRATE) {
1924-
pool = (StoragePool)dataStoreMgr.getDataStore(task.pool.getId(), DataStoreRole.Primary);
1925-
vol = migrateVolume(task.volume, pool);
1926+
store = (PrimaryDataStore) dataStoreMgr.getDataStore(task.pool.getId(), DataStoreRole.Primary);
1927+
vol = migrateVolume(task.volume, store);
19261928
} else if (task.type == VolumeTaskType.RECREATE) {
19271929
Pair<VolumeVO, DataStore> result = recreateVolume(task.volume, vm, dest);
1928-
pool = (StoragePool)dataStoreMgr.getDataStore(result.second().getId(), DataStoreRole.Primary);
1930+
store = (PrimaryDataStore) dataStoreMgr.getDataStore(result.second().getId(), DataStoreRole.Primary);
19291931
vol = result.first();
19301932
}
19311933

engine/orchestration/src/test/java/org/apache/cloudstack/engine/orchestration/VolumeOrchestratorTest.java

+55
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,13 @@
1818

1919
import java.util.ArrayList;
2020

21+
import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
22+
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
23+
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStore;
24+
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver;
25+
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
26+
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
27+
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService;
2128
import org.apache.commons.lang3.ObjectUtils;
2229
import org.junit.Assert;
2330
import org.junit.Before;
@@ -31,14 +38,22 @@
3138
import org.mockito.stubbing.Answer;
3239

3340
import com.cloud.configuration.Resource;
41+
import com.cloud.exception.StorageAccessException;
42+
import com.cloud.host.Host;
43+
import com.cloud.host.HostVO;
3444
import com.cloud.storage.VolumeVO;
3545
import com.cloud.user.ResourceLimitService;
46+
import com.cloud.utils.exception.CloudRuntimeException;
3647

3748
@RunWith(MockitoJUnitRunner.class)
3849
public class VolumeOrchestratorTest {
3950

4051
@Mock
4152
protected ResourceLimitService resourceLimitMgr;
53+
@Mock
54+
protected VolumeService volumeService;
55+
@Mock
56+
protected VolumeDataFactory volumeDataFactory;
4257

4358
@Spy
4459
@InjectMocks
@@ -100,4 +115,44 @@ public void testCheckAndUpdateVolumeAccountResourceCountMoreSize() {
100115
public void testCheckAndUpdateVolumeAccountResourceCountLessSize() {
101116
runCheckAndUpdateVolumeAccountResourceCountTest(20L, 10L);
102117
}
118+
119+
@Test
120+
public void testGrantVolumeAccessToHostIfNeededDriverNoNeed() {
121+
PrimaryDataStore store = Mockito.mock(PrimaryDataStore.class);
122+
PrimaryDataStoreDriver driver = Mockito.mock(PrimaryDataStoreDriver.class);
123+
Mockito.when(driver.volumesRequireGrantAccessWhenUsed()).thenReturn(false);
124+
Mockito.when(store.getDriver()).thenReturn(driver);
125+
volumeOrchestrator.grantVolumeAccessToHostIfNeeded(store, 1L,
126+
Mockito.mock(HostVO.class), "");
127+
Mockito.verify(volumeService, Mockito.never())
128+
.grantAccess(Mockito.any(DataObject.class), Mockito.any(Host.class), Mockito.any(DataStore.class));
129+
}
130+
131+
@Test
132+
public void testGrantVolumeAccessToHostIfNeededDriverNeeds() {
133+
PrimaryDataStore store = Mockito.mock(PrimaryDataStore.class);
134+
PrimaryDataStoreDriver driver = Mockito.mock(PrimaryDataStoreDriver.class);
135+
Mockito.when(driver.volumesRequireGrantAccessWhenUsed()).thenReturn(true);
136+
Mockito.when(store.getDriver()).thenReturn(driver);
137+
Mockito.when(volumeDataFactory.getVolume(Mockito.anyLong())).thenReturn(Mockito.mock(VolumeInfo.class));
138+
Mockito.doReturn(true).when(volumeService)
139+
.grantAccess(Mockito.any(DataObject.class), Mockito.any(Host.class), Mockito.any(DataStore.class));
140+
volumeOrchestrator.grantVolumeAccessToHostIfNeeded(store, 1L,
141+
Mockito.mock(HostVO.class), "");
142+
Mockito.verify(volumeService, Mockito.times(1))
143+
.grantAccess(Mockito.any(DataObject.class), Mockito.any(Host.class), Mockito.any(DataStore.class));
144+
}
145+
146+
@Test(expected = StorageAccessException.class)
147+
public void testGrantVolumeAccessToHostIfNeededDriverNeedsButException() {
148+
PrimaryDataStore store = Mockito.mock(PrimaryDataStore.class);
149+
PrimaryDataStoreDriver driver = Mockito.mock(PrimaryDataStoreDriver.class);
150+
Mockito.when(driver.volumesRequireGrantAccessWhenUsed()).thenReturn(true);
151+
Mockito.when(store.getDriver()).thenReturn(driver);
152+
Mockito.when(volumeDataFactory.getVolume(Mockito.anyLong())).thenReturn(Mockito.mock(VolumeInfo.class));
153+
Mockito.doThrow(CloudRuntimeException.class).when(volumeService)
154+
.grantAccess(Mockito.any(DataObject.class), Mockito.any(Host.class), Mockito.any(DataStore.class));
155+
volumeOrchestrator.grantVolumeAccessToHostIfNeeded(store, 1L,
156+
Mockito.mock(HostVO.class), "");
157+
}
103158
}

engine/schema/src/main/java/com/cloud/service/ServiceOfferingVO.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ public ServiceOfferingVO(ServiceOfferingVO offering) {
194194
limitCpuUse = offering.getLimitCpuUse();
195195
volatileVm = offering.isVolatileVm();
196196
hostTag = offering.getHostTag();
197-
vmType = offering.getSystemVmType();
197+
vmType = offering.getVmType();
198198
systemUse = offering.isSystemUse();
199199
dynamicScalingEnabled = offering.isDynamicScalingEnabled();
200200
diskOfferingStrictness = offering.diskOfferingStrictness;
@@ -278,7 +278,7 @@ public String getHostTag() {
278278
}
279279

280280
@Override
281-
public String getSystemVmType() {
281+
public String getVmType() {
282282
return vmType;
283283
}
284284

engine/schema/src/main/java/org/apache/cloudstack/acl/dao/RoleDao.java

+2
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,6 @@ public interface RoleDao extends GenericDao<RoleVO, Long> {
3737
Pair<List<RoleVO>, Integer> findAllByRoleType(RoleType type, Long offset, Long limit, boolean showPrivateRole);
3838

3939
Pair<List<RoleVO>, Integer> listAllRoles(Long startIndex, Long limit, boolean showPrivateRole);
40+
41+
List<RoleVO> searchByIds(Long... ids);
4042
}

engine/schema/src/main/java/org/apache/cloudstack/acl/dao/RoleDaoImpl.java

+17
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,13 @@
2828
import org.apache.commons.lang3.StringUtils;
2929
import org.springframework.stereotype.Component;
3030

31+
import java.util.Collections;
3132
import java.util.List;
3233

3334
@Component
3435
public class RoleDaoImpl extends GenericDaoBase<RoleVO, Long> implements RoleDao {
36+
37+
private final SearchBuilder<RoleVO> RoleByIdsSearch;
3538
private final SearchBuilder<RoleVO> RoleByNameSearch;
3639
private final SearchBuilder<RoleVO> RoleByTypeSearch;
3740
private final SearchBuilder<RoleVO> RoleByNameAndTypeSearch;
@@ -40,6 +43,10 @@ public class RoleDaoImpl extends GenericDaoBase<RoleVO, Long> implements RoleDao
4043
public RoleDaoImpl() {
4144
super();
4245

46+
RoleByIdsSearch = createSearchBuilder();
47+
RoleByIdsSearch.and("idIN", RoleByIdsSearch.entity().getId(), SearchCriteria.Op.IN);
48+
RoleByIdsSearch.done();
49+
4350
RoleByNameSearch = createSearchBuilder();
4451
RoleByNameSearch.and("roleName", RoleByNameSearch.entity().getName(), SearchCriteria.Op.LIKE);
4552
RoleByNameSearch.and("isPublicRole", RoleByNameSearch.entity().isPublicRole(), SearchCriteria.Op.EQ);
@@ -116,6 +123,16 @@ public Pair<List<RoleVO>, Integer> listAllRoles(Long startIndex, Long limit, boo
116123
return searchAndCount(sc, new Filter(RoleVO.class, "id", true, startIndex, limit));
117124
}
118125

126+
@Override
127+
public List<RoleVO> searchByIds(Long... ids) {
128+
if (ids == null || ids.length == 0) {
129+
return Collections.emptyList();
130+
}
131+
SearchCriteria<RoleVO> sc = RoleByIdsSearch.create();
132+
sc.setParameters("idIN", ids);
133+
return listBy(sc);
134+
}
135+
119136
public void filterPrivateRolesIfNeeded(SearchCriteria<RoleVO> sc, boolean showPrivateRole) {
120137
if (!showPrivateRole) {
121138
sc.setParameters("isPublicRole", true);

engine/schema/src/main/java/org/apache/cloudstack/resourcedetail/DiskOfferingDetailVO.java

+4
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ public String getName() {
6565
return name;
6666
}
6767

68+
public void setName(String name) {
69+
this.name = name;
70+
}
71+
6872
@Override
6973
public String getValue() {
7074
return value;

engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/ImageStoreDao.java

+2
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,6 @@ public interface ImageStoreDao extends GenericDao<ImageStoreVO, Long> {
5151
ImageStoreVO findOneByZoneAndProtocol(long zoneId, String protocol);
5252

5353
List<ImageStoreVO> listImageStoresByZoneIds(Long... zoneIds);
54+
55+
List<ImageStoreVO> listByIds(List<Long> ids);
5456
}

engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/ImageStoreDaoImpl.java

+16
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,14 @@
1818
*/
1919
package org.apache.cloudstack.storage.datastore.db;
2020

21+
import java.util.Collections;
2122
import java.util.List;
2223
import java.util.Map;
2324

2425
import javax.naming.ConfigurationException;
2526

2627
import com.cloud.utils.db.Filter;
28+
import org.apache.commons.collections.CollectionUtils;
2729
import org.springframework.stereotype.Component;
2830

2931
import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
@@ -44,6 +46,7 @@ public class ImageStoreDaoImpl extends GenericDaoBase<ImageStoreVO, Long> implem
4446
private SearchBuilder<ImageStoreVO> zoneProtocolSearch;
4547

4648
private SearchBuilder<ImageStoreVO> zonesInSearch;
49+
private SearchBuilder<ImageStoreVO> IdsSearch;
4750

4851
public ImageStoreDaoImpl() {
4952
super();
@@ -62,6 +65,9 @@ public ImageStoreDaoImpl() {
6265
zonesInSearch.and("zonesIn", zonesInSearch.entity().getDcId(), SearchCriteria.Op.IN);
6366
zonesInSearch.done();
6467

68+
IdsSearch = createSearchBuilder();
69+
IdsSearch.and("ids", IdsSearch.entity().getId(), SearchCriteria.Op.IN);
70+
IdsSearch.done();
6571
}
6672
@Override
6773
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
@@ -206,4 +212,14 @@ public List<ImageStoreVO> listImageStoresByZoneIds(Long... zoneIds) {
206212
sc.setParametersIfNotNull("zonesIn", zoneIds);
207213
return listBy(sc);
208214
}
215+
216+
@Override
217+
public List<ImageStoreVO> listByIds(List<Long> ids) {
218+
if (CollectionUtils.isEmpty(ids)) {
219+
return Collections.emptyList();
220+
}
221+
SearchCriteria<ImageStoreVO> sc = IdsSearch.create();
222+
sc.setParameters("ids", ids.toArray());
223+
return listBy(sc);
224+
}
209225
}

engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDao.java

+8
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
import com.cloud.storage.ScopeType;
2424
import com.cloud.storage.Storage;
2525
import com.cloud.storage.StoragePoolStatus;
26+
import com.cloud.utils.Pair;
27+
import com.cloud.utils.db.Filter;
2628
import com.cloud.utils.db.GenericDao;
2729

2830
/**
@@ -140,4 +142,10 @@ public interface PrimaryDataStoreDao extends GenericDao<StoragePoolVO, Long> {
140142
List<StoragePoolVO> findPoolsByStorageType(Storage.StoragePoolType storageType);
141143

142144
List<StoragePoolVO> listStoragePoolsWithActiveVolumesByOfferingId(long offeringid);
145+
146+
Pair<List<Long>, Integer> searchForIdsAndCount(Long storagePoolId, String storagePoolName, Long zoneId,
147+
String path, Long podId, Long clusterId, String address, ScopeType scopeType, StoragePoolStatus status,
148+
String keyword, Filter searchFilter);
149+
150+
List<StoragePoolVO> listByIds(List<Long> ids);
143151
}

0 commit comments

Comments
 (0)