mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 01:32:18 +02:00
linstor: Use template's uuid if pool's downloadPath is null as resource-name (#11053)
Also added an integration test for templates from snapshots
This commit is contained in:
parent
75a2b3cc54
commit
a4263da8ae
@ -5,6 +5,12 @@ All notable changes to Linstor CloudStack plugin will be documented in this file
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [2025-07-01]
|
||||
|
||||
### Fixed
|
||||
|
||||
- Regression in 4.19.3 and 4.21.0 with templates from snapshots
|
||||
|
||||
## [2025-05-07]
|
||||
|
||||
### Added
|
||||
|
||||
@ -619,7 +619,7 @@ public class LinstorStorageAdaptor implements StorageAdaptor {
|
||||
try {
|
||||
templateProps.load(new FileInputStream(propFile.toFile()));
|
||||
String desc = templateProps.getProperty("description");
|
||||
if (desc.startsWith("SystemVM Template")) {
|
||||
if (desc != null && desc.startsWith("SystemVM Template")) {
|
||||
return true;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
|
||||
@ -74,12 +74,14 @@ import com.cloud.storage.StorageManager;
|
||||
import com.cloud.storage.StoragePool;
|
||||
import com.cloud.storage.VMTemplateStoragePoolVO;
|
||||
import com.cloud.storage.VMTemplateStorageResourceAssoc;
|
||||
import com.cloud.storage.VMTemplateVO;
|
||||
import com.cloud.storage.Volume;
|
||||
import com.cloud.storage.VolumeDetailVO;
|
||||
import com.cloud.storage.VolumeVO;
|
||||
import com.cloud.storage.dao.SnapshotDao;
|
||||
import com.cloud.storage.dao.SnapshotDetailsDao;
|
||||
import com.cloud.storage.dao.SnapshotDetailsVO;
|
||||
import com.cloud.storage.dao.VMTemplateDao;
|
||||
import com.cloud.storage.dao.VMTemplatePoolDao;
|
||||
import com.cloud.storage.dao.VolumeDao;
|
||||
import com.cloud.storage.dao.VolumeDetailsDao;
|
||||
@ -131,6 +133,7 @@ public class LinstorPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver
|
||||
ConfigurationDao _configDao;
|
||||
@Inject
|
||||
private HostDao _hostDao;
|
||||
@Inject private VMTemplateDao _vmTemplateDao;
|
||||
|
||||
private long volumeStatsLastUpdate = 0L;
|
||||
private final Map<String, Pair<Long, Long>> volumeStats = new HashMap<>();
|
||||
@ -668,8 +671,15 @@ public class LinstorPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver
|
||||
storagePoolVO.getId(), csCloneId, null);
|
||||
|
||||
if (tmplPoolRef != null) {
|
||||
final String templateRscName = LinstorUtil.RSC_PREFIX + tmplPoolRef.getLocalDownloadPath();
|
||||
final String templateRscName;
|
||||
if (tmplPoolRef.getLocalDownloadPath() == null) {
|
||||
VMTemplateVO vmTemplateVO = _vmTemplateDao.findById(tmplPoolRef.getTemplateId());
|
||||
templateRscName = LinstorUtil.RSC_PREFIX + vmTemplateVO.getUuid();
|
||||
} else {
|
||||
templateRscName = LinstorUtil.RSC_PREFIX + tmplPoolRef.getLocalDownloadPath();
|
||||
}
|
||||
final String rscName = LinstorUtil.RSC_PREFIX + volumeInfo.getUuid();
|
||||
|
||||
final DevelopersApi linstorApi = LinstorUtil.getLinstorAPI(storagePoolVO.getHostAddress());
|
||||
|
||||
try {
|
||||
|
||||
@ -953,9 +953,72 @@ class TestLinstorVolumes(cloudstackTestCase):
|
||||
|
||||
snapshot.delete(self.apiClient)
|
||||
|
||||
@attr(tags=['basic'], required_hardware=False)
|
||||
def test_10_create_template_from_snapshot(self):
|
||||
"""
|
||||
Create a template from a snapshot and start an instance from it
|
||||
"""
|
||||
self.virtual_machine.stop(self.apiClient)
|
||||
|
||||
volume = list_volumes(
|
||||
self.apiClient,
|
||||
virtualmachineid = self.virtual_machine.id,
|
||||
type = "ROOT",
|
||||
listall = True,
|
||||
)
|
||||
snapshot = Snapshot.create(
|
||||
self.apiClient,
|
||||
volume_id=volume[0].id,
|
||||
account=self.account.name,
|
||||
domainid=self.domain.id,
|
||||
)
|
||||
self.cleanup.append(snapshot)
|
||||
|
||||
self.assertIsNotNone(snapshot, "Could not create snapshot")
|
||||
|
||||
services = {
|
||||
"displaytext": "IntegrationTestTemplate",
|
||||
"name": "int-test-template",
|
||||
"ostypeid": self.template.ostypeid,
|
||||
"ispublic": "true"
|
||||
}
|
||||
|
||||
custom_template = Template.create_from_snapshot(
|
||||
self.apiClient,
|
||||
snapshot,
|
||||
services,
|
||||
)
|
||||
self.cleanup.append(custom_template)
|
||||
|
||||
# create VM from custom template
|
||||
test_virtual_machine = VirtualMachine.create(
|
||||
self.apiClient,
|
||||
self.testdata[TestData.virtualMachine2],
|
||||
accountid=self.account.name,
|
||||
zoneid=self.zone.id,
|
||||
serviceofferingid=self.compute_offering.id,
|
||||
templateid=custom_template.id,
|
||||
domainid=self.domain.id,
|
||||
startvm=False,
|
||||
mode='basic',
|
||||
)
|
||||
self.cleanup.append(test_virtual_machine)
|
||||
|
||||
TestLinstorVolumes._start_vm(test_virtual_machine)
|
||||
|
||||
test_virtual_machine.stop(self.apiClient)
|
||||
|
||||
test_virtual_machine.delete(self.apiClient, True)
|
||||
self.cleanup.remove(test_virtual_machine)
|
||||
|
||||
custom_template.delete(self.apiClient)
|
||||
self.cleanup.remove(custom_template)
|
||||
snapshot.delete(self.apiClient)
|
||||
self.cleanup.remove(snapshot)
|
||||
|
||||
|
||||
@attr(tags=['advanced', 'migration'], required_hardware=False)
|
||||
def test_10_migrate_volume_to_same_instance_pool(self):
|
||||
def test_11_migrate_volume_to_same_instance_pool(self):
|
||||
"""Migrate volume to the same instance pool"""
|
||||
|
||||
if not self.testdata[TestData.migrationTests]:
|
||||
@ -1088,7 +1151,7 @@ class TestLinstorVolumes(cloudstackTestCase):
|
||||
test_virtual_machine.delete(self.apiClient, True)
|
||||
|
||||
@attr(tags=['advanced', 'migration'], required_hardware=False)
|
||||
def test_11_migrate_volume_to_distinct_instance_pool(self):
|
||||
def test_12_migrate_volume_to_distinct_instance_pool(self):
|
||||
"""Migrate volume to distinct instance pool"""
|
||||
|
||||
if not self.testdata[TestData.migrationTests]:
|
||||
@ -1221,7 +1284,7 @@ class TestLinstorVolumes(cloudstackTestCase):
|
||||
test_virtual_machine.delete(self.apiClient, True)
|
||||
|
||||
@attr(tags=["basic"], required_hardware=False)
|
||||
def test_12_create_vm_snapshots(self):
|
||||
def test_13_create_vm_snapshots(self):
|
||||
"""Test to create VM snapshots
|
||||
"""
|
||||
vm = TestLinstorVolumes._start_vm(self.virtual_machine)
|
||||
@ -1251,7 +1314,7 @@ class TestLinstorVolumes(cloudstackTestCase):
|
||||
)
|
||||
|
||||
@attr(tags=["basic"], required_hardware=False)
|
||||
def test_13_revert_vm_snapshots(self):
|
||||
def test_14_revert_vm_snapshots(self):
|
||||
"""Test to revert VM snapshots
|
||||
"""
|
||||
|
||||
@ -1313,7 +1376,7 @@ class TestLinstorVolumes(cloudstackTestCase):
|
||||
)
|
||||
|
||||
@attr(tags=["basic"], required_hardware=False)
|
||||
def test_14_delete_vm_snapshots(self):
|
||||
def test_15_delete_vm_snapshots(self):
|
||||
"""Test to delete vm snapshots
|
||||
"""
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user