Merge remote-tracking branch 'origin/4.19'

Signed-off-by: Rohit Yadav <rohit.yadav@shapeblue.com>
This commit is contained in:
Rohit Yadav 2024-02-09 00:13:23 +05:30
commit cfb4d4378f
6 changed files with 106 additions and 33 deletions

View File

@ -276,27 +276,35 @@ public class LinstorStorageAdaptor implements StorageAdaptor {
} }
final DevelopersApi api = getLinstorAPI(pool); final DevelopersApi api = getLinstorAPI(pool);
String rscName;
try try
{ {
final String rscName = getLinstorRscName(volumePath); rscName = getLinstorRscName(volumePath);
ResourceMakeAvailable rma = new ResourceMakeAvailable(); ResourceMakeAvailable rma = new ResourceMakeAvailable();
ApiCallRcList answers = api.resourceMakeAvailableOnNode(rscName, localNodeName, rma); ApiCallRcList answers = api.resourceMakeAvailableOnNode(rscName, localNodeName, rma);
checkLinstorAnswersThrow(answers); checkLinstorAnswersThrow(answers);
} catch (ApiException apiEx) {
s_logger.error(apiEx);
throw new CloudRuntimeException(apiEx.getBestMessage(), apiEx);
}
try
{
// allow 2 primaries for live migration, should be removed by disconnect on the other end // allow 2 primaries for live migration, should be removed by disconnect on the other end
ResourceDefinitionModify rdm = new ResourceDefinitionModify(); ResourceDefinitionModify rdm = new ResourceDefinitionModify();
Properties props = new Properties(); Properties props = new Properties();
props.put("DrbdOptions/Net/allow-two-primaries", "yes"); props.put("DrbdOptions/Net/allow-two-primaries", "yes");
rdm.setOverrideProps(props); rdm.setOverrideProps(props);
answers = api.resourceDefinitionModify(rscName, rdm); ApiCallRcList answers = api.resourceDefinitionModify(rscName, rdm);
if (answers.hasError()) { if (answers.hasError()) {
logger.error("Unable to set 'allow-two-primaries' on " + rscName); logger.error("Unable to set 'allow-two-primaries' on " + rscName);
throw new CloudRuntimeException(answers.get(0).getMessage()); // do not fail here as adding allow-two-primaries property is only a problem while live migrating
} }
} catch (ApiException apiEx) { } catch (ApiException apiEx) {
logger.error(apiEx); logger.error(apiEx);
throw new CloudRuntimeException(apiEx.getBestMessage(), apiEx); // do not fail here as adding allow-two-primaries property is only a problem while live migrating
} }
return true; return true;
} }
@ -358,21 +366,22 @@ public class LinstorStorageAdaptor implements StorageAdaptor {
ResourceDefinitionModify rdm = new ResourceDefinitionModify(); ResourceDefinitionModify rdm = new ResourceDefinitionModify();
rdm.deleteProps(Collections.singletonList("DrbdOptions/Net/allow-two-primaries")); rdm.deleteProps(Collections.singletonList("DrbdOptions/Net/allow-two-primaries"));
ApiCallRcList answers = api.resourceDefinitionModify(rsc.get().getName(), rdm); ApiCallRcList answers = api.resourceDefinitionModify(rsc.get().getName(), rdm);
if (answers.hasError()) if (answers.hasError()) {
{ logger.error(
logger.error("Failed to remove 'allow-two-primaries' on " + rsc.get().getName()); String.format("Failed to remove 'allow-two-primaries' on %s: %s",
throw new CloudRuntimeException(answers.get(0).getMessage()); rsc.get().getName(), LinstorUtil.getBestErrorMessage(answers)));
// do not fail here as removing allow-two-primaries property isn't fatal
} }
return true; return true;
} }
logger.warn("Linstor: Couldn't find resource for this path: " + localPath); logger.warn("Linstor: Couldn't find resource for this path: " + localPath);
} catch (ApiException apiEx) { } catch (ApiException apiEx) {
logger.error(apiEx); logger.error(apiEx.getBestMessage());
throw new CloudRuntimeException(apiEx.getBestMessage(), apiEx); // do not fail here as removing allow-two-primaries property isn't fatal
} }
} }
return false; return true;
} }
@Override @Override

View File

@ -191,6 +191,15 @@ public class StorPoolPrimaryDataStoreDriver implements PrimaryDataStoreDriver {
@Override @Override
public void revokeAccess(DataObject data, Host host, DataStore dataStore) { public void revokeAccess(DataObject data, Host host, DataStore dataStore) {
if (DataObjectType.VOLUME == data.getType()) {
final VolumeVO volume = volumeDao.findById(data.getId());
if (volume.getInstanceId() == null) {
StorPoolUtil.spLog("Removing tags from detached volume=%s", volume.toString());
SpConnectionDesc conn = StorPoolUtil.getSpConnection(dataStore.getUuid(), dataStore.getId(), storagePoolDetailsDao, primaryStoreDao);
StorPoolUtil.volumeRemoveTags(StorPoolStorageAdaptor.getVolumeNameFromPath(volume.getPath(), true), conn);
}
}
} }
private void updateStoragePool(final long poolId, final long deltaUsedBytes) { private void updateStoragePool(final long poolId, final long deltaUsedBytes) {
@ -1039,7 +1048,7 @@ public class StorPoolPrimaryDataStoreDriver implements PrimaryDataStoreDriver {
} }
if (vinfo.getMaxIops() != null) { if (vinfo.getMaxIops() != null) {
response = StorPoolUtil.volumeUpdateTags(volumeName, null, vinfo.getMaxIops(), conn, null); response = StorPoolUtil.volumeUpdateIopsAndTags(volumeName, null, vinfo.getMaxIops(), conn, null);
if (response.getError() != null) { if (response.getError() != null) {
StorPoolUtil.spLog("Volume was reverted successfully but max iops could not be set due to %s", response.getError().getDescr()); StorPoolUtil.spLog("Volume was reverted successfully but max iops could not be set due to %s", response.getError().getDescr());
} }
@ -1128,13 +1137,16 @@ public class StorPoolPrimaryDataStoreDriver implements PrimaryDataStoreDriver {
@Override @Override
public void provideVmInfo(long vmId, long volumeId) { public void provideVmInfo(long vmId, long volumeId) {
VolumeVO volume = volumeDao.findById(volumeId); VolumeVO volume = volumeDao.findById(volumeId);
if (volume.getInstanceId() == null) {
return;
}
StoragePoolVO poolVO = primaryStoreDao.findById(volume.getPoolId()); StoragePoolVO poolVO = primaryStoreDao.findById(volume.getPoolId());
if (poolVO != null) { if (poolVO != null) {
try { try {
SpConnectionDesc conn = StorPoolUtil.getSpConnection(poolVO.getUuid(), poolVO.getId(), storagePoolDetailsDao, primaryStoreDao); SpConnectionDesc conn = StorPoolUtil.getSpConnection(poolVO.getUuid(), poolVO.getId(), storagePoolDetailsDao, primaryStoreDao);
String volName = StorPoolStorageAdaptor.getVolumeNameFromPath(volume.getPath(), true); String volName = StorPoolStorageAdaptor.getVolumeNameFromPath(volume.getPath(), true);
VMInstanceVO userVM = vmInstanceDao.findById(vmId); VMInstanceVO userVM = vmInstanceDao.findById(vmId);
SpApiResponse resp = StorPoolUtil.volumeUpdateTags(volName, volume.getInstanceId() != null ? userVM.getUuid() : "", null, conn, getVcPolicyTag(vmId)); SpApiResponse resp = StorPoolUtil.volumeUpdateIopsAndTags(volName, volume.getInstanceId() != null ? userVM.getUuid() : "", null, conn, getVcPolicyTag(vmId));
if (resp.getError() != null) { if (resp.getError() != null) {
logger.warn(String.format("Could not update VC policy tags of a volume with id [%s]", volume.getUuid())); logger.warn(String.format("Could not update VC policy tags of a volume with id [%s]", volume.getUuid()));
} }

View File

@ -534,7 +534,14 @@ public class StorPoolUtil {
return POST("MultiCluster/VolumeUpdate/" + name, json, conn); return POST("MultiCluster/VolumeUpdate/" + name, json, conn);
} }
public static SpApiResponse volumeUpdateTags(final String name, final String uuid, Long iops, public static SpApiResponse volumeRemoveTags(String name, SpConnectionDesc conn) {
Map<String, Object> json = new HashMap<>();
Map<String, String> tags = StorPoolHelper.addStorPoolTags(null, "", null, "");
json.put("tags", tags);
return POST("MultiCluster/VolumeUpdate/" + name, json, conn);
}
public static SpApiResponse volumeUpdateIopsAndTags(final String name, final String uuid, Long iops,
SpConnectionDesc conn, String vcPolicy) { SpConnectionDesc conn, String vcPolicy) {
Map<String, Object> json = new HashMap<>(); Map<String, Object> json = new HashMap<>();
Map<String, String> tags = StorPoolHelper.addStorPoolTags(null, uuid, null, vcPolicy); Map<String, String> tags = StorPoolHelper.addStorPoolTags(null, uuid, null, vcPolicy);

View File

@ -333,7 +333,7 @@ public class StorPoolVMSnapshotStrategy extends DefaultVMSnapshotStrategy {
} }
VolumeInfo vinfo = volFactory.getVolume(volumeObjectTO.getId()); VolumeInfo vinfo = volFactory.getVolume(volumeObjectTO.getId());
if (vinfo.getMaxIops() != null) { if (vinfo.getMaxIops() != null) {
resp = StorPoolUtil.volumeUpdateTags(volumeName, null, vinfo.getMaxIops(), conn, null); resp = StorPoolUtil.volumeUpdateIopsAndTags(volumeName, null, vinfo.getMaxIops(), conn, null);
if (resp.getError() != null) { if (resp.getError() != null) {
StorPoolUtil.spLog("Volume was reverted successfully but max iops could not be set due to %s", StorPoolUtil.spLog("Volume was reverted successfully but max iops could not be set due to %s",

View File

@ -218,6 +218,19 @@ class TestStoragePool(cloudstackTestCase):
hypervisor=cls.hypervisor, hypervisor=cls.hypervisor,
rootdisksize=10 rootdisksize=10
) )
cls.virtual_machine3 = VirtualMachine.create(
cls.apiclient,
{"name":"StorPool-%s" % uuid.uuid4() },
zoneid=cls.zone.id,
templateid=template.id,
accountid=cls.account.name,
domainid=cls.account.domainid,
serviceofferingid=cls.service_offering.id,
hypervisor=cls.hypervisor,
diskofferingid=cls.disk_offerings.id,
size=2,
rootdisksize=10
)
cls.template = template cls.template = template
cls.random_data_0 = random_gen(size=100) cls.random_data_0 = random_gen(size=100)
cls.test_dir = "/tmp" cls.test_dir = "/tmp"
@ -270,7 +283,7 @@ class TestStoragePool(cloudstackTestCase):
virtualmachineid = self.virtual_machine.id, listall=True virtualmachineid = self.virtual_machine.id, listall=True
) )
self.vc_policy_tags(volumes, vm_tags, vm) self.vc_policy_tags(volumes, vm_tags, vm, True)
@attr(tags=["advanced", "advancedns", "smoke"], required_hardware="true") @attr(tags=["advanced", "advancedns", "smoke"], required_hardware="true")
@ -310,7 +323,7 @@ class TestStoragePool(cloudstackTestCase):
vm = list_virtual_machines(self.apiclient,id = self.virtual_machine.id, listall=True) vm = list_virtual_machines(self.apiclient,id = self.virtual_machine.id, listall=True)
vm_tags = vm[0].tags vm_tags = vm[0].tags
self.vc_policy_tags(volumes, vm_tags, vm) self.vc_policy_tags(volumes, vm_tags, vm, True)
self.assertEqual(volume_attached.id, self.volume.id, "Is not the same volume ") self.assertEqual(volume_attached.id, self.volume.id, "Is not the same volume ")
@ -442,7 +455,7 @@ class TestStoragePool(cloudstackTestCase):
vm = list_virtual_machines(self.apiclient,id = self.virtual_machine.id, listall=True) vm = list_virtual_machines(self.apiclient,id = self.virtual_machine.id, listall=True)
vm_tags = vm[0].tags vm_tags = vm[0].tags
self.vc_policy_tags(volumes, vm_tags, vm) self.vc_policy_tags(volumes, vm_tags, vm, True)
self.assertEqual( self.assertEqual(
self.random_data_0, self.random_data_0,
@ -490,18 +503,17 @@ class TestStoragePool(cloudstackTestCase):
def test_06_remove_vcpolicy_tag_when_disk_detached(self): def test_06_remove_vcpolicy_tag_when_disk_detached(self):
""" Test remove vc-policy tag to disk detached from VM""" """ Test remove vc-policy tag to disk detached from VM"""
time.sleep(60) time.sleep(60)
volume_detached = self.virtual_machine.detach_volume(
self.apiclient,
self.volume_2
)
vm = list_virtual_machines(self.apiclient,id = self.virtual_machine.id, listall=True) vm = list_virtual_machines(self.apiclient,id = self.virtual_machine.id, listall=True)
vm_tags = vm[0].tags vm_tags = vm[0].tags
volumes = list_volumes( volumes = list_volumes(
self.apiclient, self.apiclient,
virtualmachineid = self.virtual_machine.id, listall=True id= self.volume_2.id, listall=True,
) )
volume_detached = self.virtual_machine.detach_volume(
self.vc_policy_tags( volumes, vm_tags, vm) self.apiclient,
self.volume_2
)
self.vc_policy_tags( volumes, vm_tags, vm, False)
@attr(tags=["advanced", "advancedns", "smoke"], required_hardware="true") @attr(tags=["advanced", "advancedns", "smoke"], required_hardware="true")
def test_07_delete_vcpolicy_tag(self): def test_07_delete_vcpolicy_tag(self):
@ -538,7 +550,7 @@ class TestStoragePool(cloudstackTestCase):
virtualmachineid = self.virtual_machine2.id, listall=True, virtualmachineid = self.virtual_machine2.id, listall=True,
type = "ROOT" type = "ROOT"
) )
self.vc_policy_tags(volume, vm_tags, vm) self.vc_policy_tags(volume, vm_tags, vm, True)
snapshot = Snapshot.create( snapshot = Snapshot.create(
self.apiclient, self.apiclient,
@ -560,11 +572,36 @@ class TestStoragePool(cloudstackTestCase):
vm_tags = vm[0].tags vm_tags = vm[0].tags
vol = list_volumes(self.apiclient, id = snapshot.volumeid, listall=True) vol = list_volumes(self.apiclient, id = snapshot.volumeid, listall=True)
self.vc_policy_tags(vol, vm_tags, vm) self.vc_policy_tags(vol, vm_tags, vm, True)
@attr(tags=["advanced", "advancedns", "smoke"], required_hardware="true")
def test_09_remove_vm_tags_on_datadisks_attached_to_destroyed_vm(self):
tag = Tag.create(
self.apiclient,
resourceIds=self.virtual_machine3.id,
resourceType='UserVm',
tags={'vc-policy': 'testing_vc-policy'}
)
vm = list_virtual_machines(self.apiclient,id = self.virtual_machine3.id, listall=True)
vm_tags = vm[0].tags
volumes = list_volumes(
self.apiclient,
virtualmachineid = self.virtual_machine3.id, listall=True
)
def vc_policy_tags(self, volumes, vm_tags, vm): self.vc_policy_tags(volumes, vm_tags, vm, True)
flag = False
volumes = list_volumes(
self.apiclient,
virtualmachineid = self.virtual_machine3.id, listall=True, type="DATADISK"
)
self.virtual_machine3.delete(self.apiclient, expunge=True)
self.vc_policy_tags(volumes, vm_tags, vm, False)
def vc_policy_tags(self, volumes, vm_tags, vm, should_tags_exists=None):
vcPolicyTag = False
cvmTag = False
for v in volumes: for v in volumes:
name = v.path.split("/")[3] name = v.path.split("/")[3]
spvolume = self.spapi.volumeList(volumeName="~" + name) spvolume = self.spapi.volumeList(volumeName="~" + name)
@ -572,9 +609,15 @@ class TestStoragePool(cloudstackTestCase):
for t in tags: for t in tags:
for vm_tag in vm_tags: for vm_tag in vm_tags:
if t == vm_tag.key: if t == vm_tag.key:
flag = True vcPolicyTag = True
self.assertEqual(tags[t], vm_tag.value, "Tags are not equal") self.assertEqual(tags[t], vm_tag.value, "Tags are not equal")
if t == 'cvm': if t == 'cvm':
cvmTag = True
self.assertEqual(tags[t], vm[0].id, "CVM tag is not the same as vm UUID") self.assertEqual(tags[t], vm[0].id, "CVM tag is not the same as vm UUID")
#self.assertEqual(tag.tags., second, msg) #self.assertEqual(tag.tags., second, msg)
self.assertTrue(flag, "There aren't volumes with vm tags") if should_tags_exists:
self.assertTrue(vcPolicyTag, "There aren't volumes with vm tags")
self.assertTrue(cvmTag, "There aren't volumes with vm tags")
else:
self.assertFalse(vcPolicyTag, "The tags should be removed")
self.assertFalse(cvmTag, "The tags should be removed")

View File

@ -527,7 +527,7 @@ class VirtualMachine:
customcpuspeed=None, custommemory=None, rootdisksize=None, customcpuspeed=None, custommemory=None, rootdisksize=None,
rootdiskcontroller=None, vpcid=None, macaddress=None, datadisktemplate_diskoffering_list={}, rootdiskcontroller=None, vpcid=None, macaddress=None, datadisktemplate_diskoffering_list={},
properties=None, nicnetworklist=None, bootmode=None, boottype=None, dynamicscalingenabled=None, properties=None, nicnetworklist=None, bootmode=None, boottype=None, dynamicscalingenabled=None,
userdataid=None, userdatadetails=None, extraconfig=None): userdataid=None, userdatadetails=None, extraconfig=None, size=None):
"""Create the instance""" """Create the instance"""
cmd = deployVirtualMachine.deployVirtualMachineCmd() cmd = deployVirtualMachine.deployVirtualMachineCmd()
@ -649,7 +649,9 @@ class VirtualMachine:
if rootdiskcontroller: if rootdiskcontroller:
cmd.details[0]["rootDiskController"] = rootdiskcontroller cmd.details[0]["rootDiskController"] = rootdiskcontroller
if "size" in services: if size:
cmd.size = size
elif "size" in services:
cmd.size = services["size"] cmd.size = services["size"]
if group: if group: