mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Merge remote-tracking branch 'origin/4.19'
Signed-off-by: Rohit Yadav <rohit.yadav@shapeblue.com> Conflicts: plugins/storage/volume/linstor/src/main/java/com/cloud/hypervisor/kvm/storage/LinstorStorageAdaptor.java
This commit is contained in:
commit
93d4816ee8
@ -223,9 +223,7 @@ public class LibvirtVMDef {
|
||||
guestDef.append("<boot dev='" + bo + "'/>\n");
|
||||
}
|
||||
}
|
||||
if (_arch == null || !_arch.equals("aarch64")) {
|
||||
guestDef.append("<smbios mode='sysinfo'/>\n");
|
||||
}
|
||||
guestDef.append("<smbios mode='sysinfo'/>\n");
|
||||
guestDef.append("</os>\n");
|
||||
if (iothreads) {
|
||||
guestDef.append(String.format("<iothreads>%s</iothreads>", NUMBER_OF_IOTHREADS));
|
||||
|
||||
@ -240,6 +240,28 @@ public class LinstorStorageAdaptor implements StorageAdaptor {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given resource is in use by drbd on any host and
|
||||
* if so set the drbd option allow-two-primaries
|
||||
* @param api linstor api object
|
||||
* @param rscName resource name to set allow-two-primaries if in use
|
||||
* @throws ApiException if any problem connecting to the Linstor controller
|
||||
*/
|
||||
private void allow2PrimariesIfInUse(DevelopersApi api, String rscName) throws ApiException {
|
||||
if (LinstorUtil.isResourceInUse(api, rscName)) {
|
||||
// allow 2 primaries for live migration, should be removed by disconnect on the other end
|
||||
ResourceDefinitionModify rdm = new ResourceDefinitionModify();
|
||||
Properties props = new Properties();
|
||||
props.put("DrbdOptions/Net/allow-two-primaries", "yes");
|
||||
rdm.setOverrideProps(props);
|
||||
ApiCallRcList answers = api.resourceDefinitionModify(rscName, rdm);
|
||||
if (answers.hasError()) {
|
||||
s_logger.error("Unable to set 'allow-two-primaries' on " + rscName);
|
||||
// do not fail here as adding allow-two-primaries property is only a problem while live migrating
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean connectPhysicalDisk(String volumePath, KVMStoragePool pool, Map<String, String> details)
|
||||
{
|
||||
@ -266,16 +288,7 @@ public class LinstorStorageAdaptor implements StorageAdaptor {
|
||||
|
||||
try
|
||||
{
|
||||
// allow 2 primaries for live migration, should be removed by disconnect on the other end
|
||||
ResourceDefinitionModify rdm = new ResourceDefinitionModify();
|
||||
Properties props = new Properties();
|
||||
props.put("DrbdOptions/Net/allow-two-primaries", "yes");
|
||||
rdm.setOverrideProps(props);
|
||||
ApiCallRcList answers = api.resourceDefinitionModify(rscName, rdm);
|
||||
if (answers.hasError()) {
|
||||
logger.error("Unable to set 'allow-two-primaries' on " + rscName);
|
||||
// do not fail here as adding allow-two-primaries property is only a problem while live migrating
|
||||
}
|
||||
allow2PrimariesIfInUse(api, rscName);
|
||||
} catch (ApiException apiEx) {
|
||||
logger.error(apiEx);
|
||||
// do not fail here as adding allow-two-primaries property is only a problem while live migrating
|
||||
|
||||
@ -24,6 +24,7 @@ import com.linbit.linstor.api.model.ApiCallRc;
|
||||
import com.linbit.linstor.api.model.ApiCallRcList;
|
||||
import com.linbit.linstor.api.model.Node;
|
||||
import com.linbit.linstor.api.model.ProviderKind;
|
||||
import com.linbit.linstor.api.model.Resource;
|
||||
import com.linbit.linstor.api.model.ResourceGroup;
|
||||
import com.linbit.linstor.api.model.ResourceWithVolumes;
|
||||
import com.linbit.linstor.api.model.StoragePool;
|
||||
@ -184,4 +185,22 @@ public class LinstorUtil {
|
||||
throw new CloudRuntimeException(apiEx);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if any resource of the given name is InUse on any host.
|
||||
*
|
||||
* @param api developer api object to use
|
||||
* @param rscName resource name to check in use state.
|
||||
* @return True if a resource found that is in use(primary) state, else false.
|
||||
* @throws ApiException forwards api errors
|
||||
*/
|
||||
public static boolean isResourceInUse(DevelopersApi api, String rscName) throws ApiException {
|
||||
List<Resource> rscs = api.resourceList(rscName, null, null);
|
||||
if (rscs != null) {
|
||||
return rscs.stream()
|
||||
.anyMatch(rsc -> rsc.getState() != null && Boolean.TRUE.equals(rsc.getState().isInUse()));
|
||||
}
|
||||
s_logger.error("isResourceInUse: null returned from resourceList");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -351,6 +351,9 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
|
||||
if (possibleAddr.getState() != State.Free) {
|
||||
continue;
|
||||
}
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug(String.format("trying ip address %s", possibleAddr.getAddress()));
|
||||
}
|
||||
possibleAddr.setSourceNat(sourceNat);
|
||||
possibleAddr.setAllocatedTime(new Date());
|
||||
possibleAddr.setAllocatedInDomainId(owner.getDomainId());
|
||||
@ -365,15 +368,9 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
|
||||
possibleAddr.setAssociatedWithNetworkId(guestNetworkId);
|
||||
possibleAddr.setVpcId(vpcId);
|
||||
}
|
||||
if (_ipAddressDao.lockRow(possibleAddr.getId(), true) != null) {
|
||||
final IPAddressVO userIp = _ipAddressDao.findById(possibleAddr.getId());
|
||||
if (userIp.getState() == State.Free) {
|
||||
possibleAddr.setState(State.Allocating);
|
||||
if (_ipAddressDao.update(possibleAddr.getId(), possibleAddr)) {
|
||||
finalAddress = possibleAddr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
finalAddress = assignIpAddressWithLock(possibleAddr);
|
||||
if (finalAddress != null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -395,6 +392,29 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
|
||||
});
|
||||
}
|
||||
|
||||
private IPAddressVO assignIpAddressWithLock(IPAddressVO possibleAddr) {
|
||||
IPAddressVO finalAddress = null;
|
||||
IPAddressVO userIp = _ipAddressDao.acquireInLockTable(possibleAddr.getId());
|
||||
if (userIp != null) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug(String.format("locked row for ip address %s (id: %s)", possibleAddr.getAddress(), possibleAddr.getUuid()));
|
||||
}
|
||||
if (userIp.getState() == State.Free) {
|
||||
possibleAddr.setState(State.Allocating);
|
||||
if (_ipAddressDao.update(possibleAddr.getId(), possibleAddr)) {
|
||||
s_logger.info(String.format("successfully allocated ip address %s", possibleAddr.getAddress()));
|
||||
finalAddress = possibleAddr;
|
||||
}
|
||||
} else {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug(String.format("locked ip address %s is not free (%s)", possibleAddr.getAddress(), userIp.getState()));
|
||||
}
|
||||
}
|
||||
_ipAddressDao.releaseFromLockTable(possibleAddr.getId());
|
||||
}
|
||||
return finalAddress;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean configure(String name, Map<String, Object> params) {
|
||||
// populate providers
|
||||
|
||||
@ -26,7 +26,7 @@
|
||||
<a-button
|
||||
type="dashed"
|
||||
style="width: 100%"
|
||||
:disabled="!('updateTemplate' in $store.getters.apis && 'updateVirtualMachine' in $store.getters.apis && isAdminOrOwner())"
|
||||
:disabled="!(isAdminOrOwner() && hasSettingUpdatePermission())"
|
||||
@click="onShowAddDetail">
|
||||
<template #icon><plus-outlined /></template>
|
||||
{{ $t('label.add.setting') }}
|
||||
@ -96,8 +96,7 @@
|
||||
</a-list-item-meta>
|
||||
<template #actions>
|
||||
<div
|
||||
v-if="!disableSettings && 'updateTemplate' in $store.getters.apis &&
|
||||
'updateVirtualMachine' in $store.getters.apis && isAdminOrOwner() && allowEditOfDetail(item.name)">
|
||||
v-if="!disableSettings && isAdminOrOwner() && allowEditOfDetail(item.name) && hasSettingUpdatePermission()">
|
||||
<tooltip-button
|
||||
:tooltip="$t('label.edit')"
|
||||
icon="edit-outlined"
|
||||
@ -106,8 +105,7 @@
|
||||
@onClick="showEditDetail(index)" />
|
||||
</div>
|
||||
<div
|
||||
v-if="!disableSettings && 'updateTemplate' in $store.getters.apis &&
|
||||
'updateVirtualMachine' in $store.getters.apis && isAdminOrOwner() && allowEditOfDetail(item.name)">
|
||||
v-if="!disableSettings && isAdminOrOwner() && allowEditOfDetail(item.name) && hasSettingUpdatePermission()">
|
||||
<a-popconfirm
|
||||
:title="`${$t('label.delete.setting')}?`"
|
||||
@confirm="deleteDetail(index)"
|
||||
@ -342,6 +340,12 @@ export default {
|
||||
this.newValue = ''
|
||||
this.error = false
|
||||
this.showAddDetail = false
|
||||
},
|
||||
hasSettingUpdatePermission () {
|
||||
return (
|
||||
(this.resourceType === 'Template' && 'updateTemplate' in this.$store.getters.apis) ||
|
||||
(this.resourceType === 'UserVm' && 'updateVirtualMachine' in this.$store.getters.apis)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user