Skip to content

Commit e720b72

Browse files
committed
Merge remote-tracking branch 'apache/4.17' into main
2 parents d4b8e2c + a21efe7 commit e720b72

File tree

11 files changed

+302
-123
lines changed

11 files changed

+302
-123
lines changed

core/src/main/java/org/apache/cloudstack/storage/to/PrimaryDataStoreTO.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ public class PrimaryDataStoreTO implements DataStoreTO {
5555
private Boolean diskProvisioningStrictnessFlag;
5656
private final boolean isManaged;
5757

58+
private final StoragePoolType parentPoolType;
59+
5860
public PrimaryDataStoreTO(PrimaryDataStore dataStore) {
5961
this.uuid = dataStore.getUuid();
6062
this.name = dataStore.getName();
@@ -66,6 +68,7 @@ public PrimaryDataStoreTO(PrimaryDataStore dataStore) {
6668
this.url = dataStore.getUri();
6769
this.details = dataStore.getDetails();
6870
this.isManaged = dataStore.isManaged();
71+
this.parentPoolType = dataStore.getParentPoolType();
6972
}
7073

7174
public long getId() {
@@ -172,4 +175,8 @@ public Boolean getDiskProvisioningStrictnessFlag() {
172175
public void setDiskProvisioningStrictnessFlag(Boolean diskProvisioningStrictnessFlag) {
173176
this.diskProvisioningStrictnessFlag = diskProvisioningStrictnessFlag;
174177
}
178+
179+
public StoragePoolType getParentPoolType() {
180+
return parentPoolType;
181+
}
175182
}

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222

2323
import org.apache.cloudstack.engine.subsystem.api.storage.disktype.DiskFormat;
2424

25+
import com.cloud.storage.Storage;
26+
2527
public interface PrimaryDataStore extends DataStore, PrimaryDataStoreInfo {
2628
DataObject create(DataObject dataObject, String configuration);
2729

@@ -38,4 +40,6 @@ public interface PrimaryDataStore extends DataStore, PrimaryDataStoreInfo {
3840
SnapshotInfo getSnapshot(long snapshotId);
3941

4042
DiskFormat getDefaultDiskType();
43+
44+
Storage.StoragePoolType getParentPoolType();
4145
}

engine/storage/snapshot/src/main/java/org/apache/cloudstack/storage/vmsnapshot/DefaultVMSnapshotStrategy.java

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,14 @@
2525
import javax.inject.Inject;
2626
import javax.naming.ConfigurationException;
2727

28-
import com.cloud.event.UsageEventVO;
29-
import org.apache.log4j.Logger;
30-
3128
import org.apache.cloudstack.engine.subsystem.api.storage.StrategyPriority;
3229
import org.apache.cloudstack.engine.subsystem.api.storage.VMSnapshotOptions;
3330
import org.apache.cloudstack.engine.subsystem.api.storage.VMSnapshotStrategy;
3431
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
32+
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
3533
import org.apache.cloudstack.storage.to.VolumeObjectTO;
34+
import org.apache.commons.lang3.StringUtils;
35+
import org.apache.log4j.Logger;
3636

3737
import com.cloud.agent.AgentManager;
3838
import com.cloud.agent.api.Answer;
@@ -45,6 +45,7 @@
4545
import com.cloud.agent.api.VMSnapshotTO;
4646
import com.cloud.event.EventTypes;
4747
import com.cloud.event.UsageEventUtils;
48+
import com.cloud.event.UsageEventVO;
4849
import com.cloud.exception.AgentUnavailableException;
4950
import com.cloud.exception.OperationTimedoutException;
5051
import com.cloud.host.HostVO;
@@ -53,6 +54,7 @@
5354
import com.cloud.storage.GuestOSHypervisorVO;
5455
import com.cloud.storage.GuestOSVO;
5556
import com.cloud.storage.Storage.ImageFormat;
57+
import com.cloud.storage.StoragePool;
5658
import com.cloud.storage.VolumeVO;
5759
import com.cloud.storage.dao.DiskOfferingDao;
5860
import com.cloud.storage.dao.GuestOSDao;
@@ -97,6 +99,8 @@ public class DefaultVMSnapshotStrategy extends ManagerBase implements VMSnapshot
9799
DiskOfferingDao diskOfferingDao;
98100
@Inject
99101
HostDao hostDao;
102+
@Inject
103+
PrimaryDataStoreDao primaryDataStoreDao;
100104

101105
@Override
102106
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
@@ -323,14 +327,26 @@ protected void finalizeRevert(VMSnapshotVO vmSnapshot, List<VolumeObjectTO> volu
323327
vmSnapshotDao.persist(vmSnapshot);
324328
}
325329

326-
private void updateVolumePath(List<VolumeObjectTO> volumeTOs) {
330+
protected void updateVolumePath(List<VolumeObjectTO> volumeTOs) {
327331
for (VolumeObjectTO volume : volumeTOs) {
328-
if (volume.getPath() != null) {
329-
VolumeVO volumeVO = volumeDao.findById(volume.getId());
332+
if (StringUtils.isAllEmpty(volume.getDataStoreUuid(), volume.getPath(), volume.getChainInfo())) {
333+
continue;
334+
}
335+
VolumeVO volumeVO = volumeDao.findById(volume.getId());
336+
if (StringUtils.isNotEmpty(volume.getDataStoreUuid())) {
337+
StoragePool pool = primaryDataStoreDao.findPoolByUUID(volume.getDataStoreUuid());
338+
if (pool != null && pool.getId() != volumeVO.getPoolId()) {
339+
volumeVO.setPoolId(pool.getId());
340+
}
341+
}
342+
if (StringUtils.isNotEmpty(volume.getPath())) {
330343
volumeVO.setPath(volume.getPath());
331-
volumeVO.setVmSnapshotChainSize(volume.getSize());
332-
volumeDao.persist(volumeVO);
333344
}
345+
if (StringUtils.isNotEmpty(volume.getChainInfo())) {
346+
volumeVO.setChainInfo(volume.getChainInfo());
347+
}
348+
volumeVO.setVmSnapshotChainSize(volume.getSize());
349+
volumeDao.persist(volumeVO);
334350
}
335351
}
336352

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.apache.cloudstack.storage.vmsnapshot;
20+
21+
import java.util.ArrayList;
22+
import java.util.List;
23+
import java.util.UUID;
24+
25+
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
26+
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
27+
import org.apache.cloudstack.storage.to.VolumeObjectTO;
28+
import org.junit.Assert;
29+
import org.junit.Test;
30+
import org.junit.runner.RunWith;
31+
import org.mockito.InjectMocks;
32+
import org.mockito.Mock;
33+
import org.mockito.Mockito;
34+
import org.mockito.Spy;
35+
import org.mockito.junit.MockitoJUnitRunner;
36+
import org.mockito.stubbing.Answer;
37+
38+
import com.cloud.storage.Storage;
39+
import com.cloud.storage.Volume;
40+
import com.cloud.storage.VolumeVO;
41+
import com.cloud.storage.dao.VolumeDao;
42+
43+
@RunWith(MockitoJUnitRunner.class)
44+
public class DefaultVMSnapshotStrategyTest {
45+
@Mock
46+
VolumeDao volumeDao;
47+
@Mock
48+
PrimaryDataStoreDao primaryDataStoreDao;
49+
50+
@Spy
51+
@InjectMocks
52+
private final DefaultVMSnapshotStrategy defaultVMSnapshotStrategy = new DefaultVMSnapshotStrategy();
53+
54+
protected List<VolumeVO> persistedVolumes = new ArrayList<>();
55+
56+
57+
private void setupVolumeDaoPersistMock() {
58+
persistedVolumes.clear();
59+
Mockito.when(volumeDao.persist(Mockito.any())).thenAnswer((Answer<VolumeVO>) invocation -> {
60+
VolumeVO volume = (VolumeVO)invocation.getArguments()[0];
61+
persistedVolumes.add(volume);
62+
return volume;
63+
});
64+
}
65+
66+
@Test
67+
public void testUpdateVolumePath() {
68+
setupVolumeDaoPersistMock();
69+
VolumeObjectTO vol1 = Mockito.mock(VolumeObjectTO.class);
70+
Mockito.when(vol1.getDataStoreUuid()).thenReturn(null);
71+
Mockito.when(vol1.getPath()).thenReturn(null);
72+
Mockito.when(vol1.getChainInfo()).thenReturn(null);
73+
VolumeObjectTO vol2 = Mockito.mock(VolumeObjectTO.class);
74+
Long volumeId = 1L;
75+
String newDSUuid = UUID.randomUUID().toString();
76+
String oldVolPath = "old";
77+
String newVolPath = "new";
78+
String oldVolChain = "old-chain";
79+
String newVolChain = "new-chain";
80+
Long vmSnapshotChainSize = 1000L;
81+
Long oldPoolId = 1L;
82+
Long newPoolId = 2L;
83+
Mockito.when(vol2.getDataStoreUuid()).thenReturn(newDSUuid);
84+
Mockito.when(vol2.getPath()).thenReturn(newVolPath);
85+
Mockito.when(vol2.getChainInfo()).thenReturn(newVolChain);
86+
Mockito.when(vol2.getSize()).thenReturn(vmSnapshotChainSize);
87+
Mockito.when(vol2.getId()).thenReturn(volumeId);
88+
VolumeVO volumeVO = new VolumeVO("name", 0l, 0l, 0l, 0l, 0l, "folder", "path", Storage.ProvisioningType.THIN, 0l, Volume.Type.ROOT);
89+
volumeVO.setPoolId(oldPoolId);
90+
volumeVO.setChainInfo(oldVolChain);
91+
volumeVO.setPath(oldVolPath);
92+
Mockito.when(volumeDao.findById(volumeId)).thenReturn(volumeVO);
93+
StoragePoolVO storagePoolVO = Mockito.mock(StoragePoolVO.class);
94+
Mockito.when(storagePoolVO.getId()).thenReturn(newPoolId);
95+
Mockito.when(primaryDataStoreDao.findPoolByUUID(newDSUuid)).thenReturn(storagePoolVO);
96+
Mockito.when(volumeDao.findById(volumeId)).thenReturn(volumeVO);
97+
defaultVMSnapshotStrategy.updateVolumePath(List.of(vol1, vol2));
98+
Assert.assertEquals(1, persistedVolumes.size());
99+
VolumeVO persistedVolume = persistedVolumes.get(0);
100+
Assert.assertNotNull(persistedVolume);
101+
Assert.assertEquals(newPoolId, persistedVolume.getPoolId());
102+
Assert.assertEquals(newVolPath, persistedVolume.getPath());
103+
Assert.assertEquals(vmSnapshotChainSize, persistedVolume.getVmSnapshotChainSize());
104+
Assert.assertEquals(newVolChain, persistedVolume.getChainInfo());
105+
}
106+
}

engine/storage/snapshot/src/test/java/org/apache/cloudstack/storage/vmsnapshot/VMSnapshotStrategyTest.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
import org.apache.cloudstack.engine.subsystem.api.storage.VMSnapshotStrategy;
2929
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
30+
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
3031
import org.apache.cloudstack.storage.to.VolumeObjectTO;
3132
import org.apache.cloudstack.test.utils.SpringUtils;
3233
import org.junit.Before;
@@ -92,6 +93,8 @@ public class VMSnapshotStrategyTest extends TestCase {
9293
VMSnapshotDao vmSnapshotDao;
9394
@Inject
9495
HostDao hostDao;
96+
@Inject
97+
PrimaryDataStoreDao primaryDataStoreDao;
9598

9699
@Override
97100
@Before
@@ -304,5 +307,10 @@ public DiskOfferingDao diskOfferingDao() {
304307
public HostDao hostDao() {
305308
return Mockito.mock(HostDao.class);
306309
}
310+
311+
@Bean
312+
public PrimaryDataStoreDao primaryDataStoreDao() {
313+
return Mockito.mock(PrimaryDataStoreDao.class);
314+
}
307315
}
308316
}

engine/storage/volume/src/main/java/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ public class PrimaryDataStoreImpl implements PrimaryDataStore {
7272

7373
protected PrimaryDataStoreDriver driver;
7474
protected StoragePoolVO pdsv;
75+
protected StoragePoolVO parentStoragePool;
7576
@Inject
7677
protected PrimaryDataStoreDao dataStoreDao;
7778
protected PrimaryDataStoreLifeCycle lifeCycle;
@@ -104,6 +105,9 @@ public void configure(StoragePoolVO pdsv, PrimaryDataStoreDriver driver, DataSto
104105
this.provider = provider;
105106
this.uuid = pdsv.getUuid();
106107
this.name = pdsv.getName();
108+
if (pdsv.getParent() != null && pdsv.getParent() > 0L) {
109+
this.parentStoragePool = dataStoreDao.findById(pdsv.getParent());
110+
}
107111
}
108112

109113
public static PrimaryDataStoreImpl createDataStore(StoragePoolVO pdsv, PrimaryDataStoreDriver driver, DataStoreProvider provider) {
@@ -452,4 +456,12 @@ public DataStoreTO getTO() {
452456
}
453457
return to;
454458
}
459+
460+
@Override
461+
public StoragePoolType getParentPoolType() {
462+
if (this.parentStoragePool != null) {
463+
return this.parentStoragePool.getPoolType();
464+
}
465+
return null;
466+
}
455467
}

plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareHostService.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import com.cloud.hypervisor.vmware.mo.DatastoreMO;
2121
import com.cloud.hypervisor.vmware.mo.VmwareHypervisorHost;
2222
import com.cloud.hypervisor.vmware.util.VmwareContext;
23+
import com.cloud.storage.resource.VmwareStorageProcessor;
2324

2425
public interface VmwareHostService {
2526
VmwareContext getServiceContext(Command cmd);
@@ -31,4 +32,6 @@ public interface VmwareHostService {
3132
String getWorkerName(VmwareContext context, Command cmd, int workerSequence, DatastoreMO dsMo) throws Exception;
3233

3334
String createLogMessageException(Throwable e, Command command);
35+
36+
VmwareStorageProcessor getStorageProcessor();
3437
}

0 commit comments

Comments
 (0)