mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Merge branch '4.20'
This commit is contained in:
commit
8af021c6f6
@ -20,6 +20,19 @@ import os
|
||||
import logging
|
||||
import sys
|
||||
import socket
|
||||
|
||||
# ---- This snippet of code adds the sources path and the waf configured PYTHONDIR to the Python path ----
|
||||
# ---- We do this so cloud_utils can be looked up in the following order:
|
||||
# ---- 1) Sources directory
|
||||
# ---- 2) waf configured PYTHONDIR
|
||||
# ---- 3) System Python path
|
||||
for pythonpath in (
|
||||
"@PYTHONDIR@",
|
||||
os.path.join(os.path.dirname(__file__),os.path.pardir,os.path.pardir,"python","lib"),
|
||||
):
|
||||
if os.path.isdir(pythonpath): sys.path.insert(0,pythonpath)
|
||||
# ---- End snippet of code ----
|
||||
|
||||
from cloudutils.cloudException import CloudRuntimeException, CloudInternalException
|
||||
from cloudutils.utilities import initLoging, bash
|
||||
from cloudutils.configFileOps import configFileOps
|
||||
|
||||
@ -20,6 +20,19 @@ import sys
|
||||
import os
|
||||
import subprocess
|
||||
from threading import Timer
|
||||
|
||||
# ---- This snippet of code adds the sources path and the waf configured PYTHONDIR to the Python path ----
|
||||
# ---- We do this so cloud_utils can be looked up in the following order:
|
||||
# ---- 1) Sources directory
|
||||
# ---- 2) waf configured PYTHONDIR
|
||||
# ---- 3) System Python path
|
||||
for pythonpath in (
|
||||
"@PYTHONDIR@",
|
||||
os.path.join(os.path.dirname(__file__),os.path.pardir,os.path.pardir,"python","lib"),
|
||||
):
|
||||
if os.path.isdir(pythonpath): sys.path.insert(0,pythonpath)
|
||||
# ---- End snippet of code ----
|
||||
|
||||
from xml.dom.minidom import parse
|
||||
from cloudutils.configFileOps import configFileOps
|
||||
from cloudutils.networkConfig import networkConfig
|
||||
|
||||
@ -28,12 +28,11 @@ import org.apache.cloudstack.api.BaseResponseWithAssociatedNetwork;
|
||||
import org.apache.cloudstack.api.EntityReference;
|
||||
|
||||
import com.cloud.network.Network;
|
||||
import com.cloud.projects.ProjectAccount;
|
||||
import com.cloud.serializer.Param;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@EntityReference(value = {Network.class, ProjectAccount.class})
|
||||
@EntityReference(value = {Network.class})
|
||||
public class NetworkResponse extends BaseResponseWithAssociatedNetwork implements ControlledEntityResponse, SetResourceIconResponse {
|
||||
|
||||
@SerializedName(ApiConstants.ID)
|
||||
|
||||
@ -16,13 +16,27 @@
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import os
|
||||
import sys
|
||||
# ---- This snippet of code adds the sources path and the waf configured PYTHONDIR to the Python path ----
|
||||
# ---- We do this so cloud_utils can be looked up in the following order:
|
||||
# ---- 1) Sources directory
|
||||
# ---- 2) waf configured PYTHONDIR
|
||||
# ---- 3) System Python path
|
||||
for pythonpath in (
|
||||
"@PYTHONDIR@",
|
||||
os.path.join(os.path.dirname(__file__),os.path.pardir,os.path.pardir,"python","lib"),
|
||||
):
|
||||
if os.path.isdir(pythonpath): sys.path.insert(0,pythonpath)
|
||||
# ---- End snippet of code ----
|
||||
|
||||
from cloudutils.syscfg import sysConfigFactory
|
||||
from cloudutils.utilities import initLoging, UnknownSystemException
|
||||
from cloudutils.cloudException import CloudRuntimeException, CloudInternalException
|
||||
from cloudutils.globalEnv import globalEnv
|
||||
from cloudutils.serviceConfigServer import cloudManagementConfig
|
||||
from optparse import OptionParser
|
||||
|
||||
if __name__ == '__main__':
|
||||
initLoging("@MSLOGDIR@/setupManagement.log")
|
||||
glbEnv = globalEnv()
|
||||
|
||||
@ -22,14 +22,16 @@ import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import com.cloud.dc.dao.DataCenterDao;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
|
||||
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
||||
import org.apache.cloudstack.storage.volume.datastore.PrimaryDataStoreHelper;
|
||||
|
||||
import com.cloud.agent.AgentManager;
|
||||
import com.cloud.agent.api.Answer;
|
||||
import com.cloud.agent.api.DeleteStoragePoolCommand;
|
||||
import com.cloud.dc.dao.DataCenterDao;
|
||||
import com.cloud.host.HostVO;
|
||||
import com.cloud.host.dao.HostDao;
|
||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
@ -37,8 +39,12 @@ import com.cloud.resource.ResourceManager;
|
||||
import com.cloud.storage.StorageManager;
|
||||
import com.cloud.storage.StoragePool;
|
||||
import com.cloud.storage.StoragePoolHostVO;
|
||||
import com.cloud.storage.VMTemplateStoragePoolVO;
|
||||
import com.cloud.storage.VMTemplateStorageResourceAssoc;
|
||||
import com.cloud.storage.dao.StoragePoolHostDao;
|
||||
import com.cloud.template.TemplateManager;
|
||||
import com.cloud.utils.Pair;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
@ -59,6 +65,10 @@ public class BasePrimaryDataStoreLifeCycleImpl {
|
||||
protected DataCenterDao zoneDao;
|
||||
@Inject
|
||||
protected StoragePoolHostDao storagePoolHostDao;
|
||||
@Inject
|
||||
private PrimaryDataStoreDao primaryDataStoreDao;
|
||||
@Inject
|
||||
private TemplateManager templateMgr;
|
||||
|
||||
private List<HostVO> getPoolHostsList(ClusterScope clusterScope, HypervisorType hypervisorType) {
|
||||
List<HostVO> hosts;
|
||||
@ -81,7 +91,7 @@ public class BasePrimaryDataStoreLifeCycleImpl {
|
||||
try {
|
||||
storageMgr.connectHostToSharedPool(host, store.getId());
|
||||
} catch (Exception e) {
|
||||
logger.warn("Unable to establish a connection between " + host + " and " + store, e);
|
||||
logger.warn("Unable to establish a connection between {} and {}", host, store, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -99,7 +109,7 @@ public class BasePrimaryDataStoreLifeCycleImpl {
|
||||
|
||||
if (answer != null) {
|
||||
if (!answer.getResult()) {
|
||||
logger.debug("Failed to delete storage pool: " + answer.getResult());
|
||||
logger.debug("Failed to delete storage pool: {}", answer.getResult());
|
||||
} else if (HypervisorType.KVM != hypervisorType) {
|
||||
break;
|
||||
}
|
||||
@ -108,4 +118,42 @@ public class BasePrimaryDataStoreLifeCycleImpl {
|
||||
}
|
||||
dataStoreHelper.switchToCluster(store, clusterScope);
|
||||
}
|
||||
|
||||
private void evictTemplates(StoragePoolVO storagePoolVO) {
|
||||
List<VMTemplateStoragePoolVO> unusedTemplatesInPool = templateMgr.getUnusedTemplatesInPool(storagePoolVO);
|
||||
for (VMTemplateStoragePoolVO templatePoolVO : unusedTemplatesInPool) {
|
||||
if (templatePoolVO.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) {
|
||||
templateMgr.evictTemplateFromStoragePool(templatePoolVO);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void deleteAgentStoragePools(StoragePool storagePool) {
|
||||
List<StoragePoolHostVO> poolHostVOs = storagePoolHostDao.listByPoolId(storagePool.getId());
|
||||
for (StoragePoolHostVO poolHostVO : poolHostVOs) {
|
||||
DeleteStoragePoolCommand deleteStoragePoolCommand = new DeleteStoragePoolCommand(storagePool);
|
||||
final Answer answer = agentMgr.easySend(poolHostVO.getHostId(), deleteStoragePoolCommand);
|
||||
if (answer != null && answer.getResult()) {
|
||||
logger.info("Successfully deleted storage pool: {} from host: {}", storagePool.getId(), poolHostVO.getHostId());
|
||||
} else {
|
||||
if (answer != null) {
|
||||
logger.error("Failed to delete storage pool: {} from host: {} , result: {}", storagePool.getId(), poolHostVO.getHostId(), answer.getResult());
|
||||
} else {
|
||||
logger.error("Failed to delete storage pool: {} from host: {}", storagePool.getId(), poolHostVO.getHostId());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean cleanupDatastore(DataStore store) {
|
||||
StoragePool storagePool = (StoragePool)store;
|
||||
StoragePoolVO storagePoolVO = primaryDataStoreDao.findById(storagePool.getId());
|
||||
if (storagePoolVO == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
evictTemplates(storagePoolVO);
|
||||
deleteAgentStoragePools(storagePool);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -85,7 +85,7 @@ public class ConfigDepotImpl implements ConfigDepot, ConfigDepotAdmin {
|
||||
List<ScopedConfigStorage> _scopedStorages;
|
||||
Set<Configurable> _configured = Collections.synchronizedSet(new HashSet<Configurable>());
|
||||
Set<String> newConfigs = Collections.synchronizedSet(new HashSet<>());
|
||||
LazyCache<String, String> configCache;
|
||||
LazyCache<Ternary<String, ConfigKey.Scope, Long>, String> configCache;
|
||||
|
||||
private HashMap<String, Pair<String, ConfigKey<?>>> _allKeys = new HashMap<String, Pair<String, ConfigKey<?>>>(1007);
|
||||
|
||||
@ -275,15 +275,10 @@ public class ConfigDepotImpl implements ConfigDepot, ConfigDepotAdmin {
|
||||
return _configDao;
|
||||
}
|
||||
|
||||
protected String getConfigStringValueInternal(String cacheKey) {
|
||||
String[] parts = cacheKey.split("-");
|
||||
String key = parts[0];
|
||||
ConfigKey.Scope scope = ConfigKey.Scope.Global;
|
||||
Long scopeId = null;
|
||||
try {
|
||||
scope = ConfigKey.Scope.valueOf(parts[1]);
|
||||
scopeId = Long.valueOf(parts[2]);
|
||||
} catch (IllegalArgumentException ignored) {}
|
||||
protected String getConfigStringValueInternal(Ternary<String, ConfigKey.Scope, Long> cacheKey) {
|
||||
String key = cacheKey.first();
|
||||
ConfigKey.Scope scope = cacheKey.second();
|
||||
Long scopeId = cacheKey.third();
|
||||
if (!ConfigKey.Scope.Global.equals(scope) && scopeId != null) {
|
||||
ScopedConfigStorage scopedConfigStorage = getScopedStorage(scope);
|
||||
if (scopedConfigStorage == null) {
|
||||
@ -298,8 +293,8 @@ public class ConfigDepotImpl implements ConfigDepot, ConfigDepotAdmin {
|
||||
return null;
|
||||
}
|
||||
|
||||
private String getConfigCacheKey(String key, ConfigKey.Scope scope, Long scopeId) {
|
||||
return String.format("%s-%s-%d", key, scope, (scopeId == null ? 0 : scopeId));
|
||||
protected Ternary<String, ConfigKey.Scope, Long> getConfigCacheKey(String key, ConfigKey.Scope scope, Long scopeId) {
|
||||
return new Ternary<>(key, scope, scopeId);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -89,6 +89,12 @@ public class ConfigDepotImplTest {
|
||||
runTestGetConfigStringValue("test", "value");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetConfigStringValue_nameWithCharacters() {
|
||||
runTestGetConfigStringValue("test.1-1", "value");
|
||||
runTestGetConfigStringValue("test_1#2", "value");
|
||||
}
|
||||
|
||||
private void runTestGetConfigStringValueExpiry(long wait, int configDBRetrieval) {
|
||||
String key = "test1";
|
||||
String value = "expiry";
|
||||
|
||||
@ -49,8 +49,12 @@ public class GenericPresetVariable {
|
||||
fieldNamesToIncludeInToString.add("name");
|
||||
}
|
||||
|
||||
/***
|
||||
* Converts the preset variable into a valid JSON object that will be injected into the JS interpreter.
|
||||
* This method should not be overridden or changed.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
public final String toString() {
|
||||
return ReflectionToStringBuilderUtils.reflectOnlySelectedFields(this, fieldNamesToIncludeInToString.toArray(new String[0]));
|
||||
}
|
||||
}
|
||||
|
||||
@ -40,8 +40,12 @@ public class Resource {
|
||||
this.domainId = domainId;
|
||||
}
|
||||
|
||||
/***
|
||||
* Converts the preset variable into a valid JSON object that will be injected into the JS interpreter.
|
||||
* This method should not be overridden or changed.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
public final String toString() {
|
||||
return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
|
||||
}
|
||||
|
||||
|
||||
@ -189,13 +189,6 @@ public class MetricsServiceImpl extends MutualExclusiveIdsManagerBase implements
|
||||
super();
|
||||
}
|
||||
|
||||
private Double findRatioValue(final String value) {
|
||||
if (value != null) {
|
||||
return Double.valueOf(value);
|
||||
}
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
private void updateHostMetrics(final HostMetrics hostMetrics, final HostJoinVO host) {
|
||||
hostMetrics.addCpuAllocated(host.getCpuReservedCapacity() + host.getCpuUsedCapacity());
|
||||
hostMetrics.addMemoryAllocated(host.getMemReservedCapacity() + host.getMemUsedCapacity());
|
||||
@ -767,14 +760,10 @@ public class MetricsServiceImpl extends MutualExclusiveIdsManagerBase implements
|
||||
if (AllowListMetricsComputation.value()) {
|
||||
List<Ternary<Long, Long, Long>> cpuList = new ArrayList<>();
|
||||
List<Ternary<Long, Long, Long>> memoryList = new ArrayList<>();
|
||||
for (final Host host : hostDao.findByClusterId(clusterId)) {
|
||||
if (host == null || host.getType() != Host.Type.Routing) {
|
||||
continue;
|
||||
}
|
||||
updateHostMetrics(hostMetrics, hostJoinDao.findById(host.getId()));
|
||||
HostJoinVO hostJoin = hostJoinDao.findById(host.getId());
|
||||
cpuList.add(new Ternary<>(hostJoin.getCpuUsedCapacity(), hostJoin.getCpuReservedCapacity(), hostJoin.getCpus() * hostJoin.getSpeed()));
|
||||
memoryList.add(new Ternary<>(hostJoin.getMemUsedCapacity(), hostJoin.getMemReservedCapacity(), hostJoin.getTotalMemory()));
|
||||
for (final HostJoinVO host : hostJoinDao.findByClusterId(clusterId, Host.Type.Routing)) {
|
||||
updateHostMetrics(hostMetrics, host);
|
||||
cpuList.add(new Ternary<>(host.getCpuUsedCapacity(), host.getCpuReservedCapacity(), host.getCpus() * host.getSpeed()));
|
||||
memoryList.add(new Ternary<>(host.getMemUsedCapacity(), host.getMemReservedCapacity(), host.getTotalMemory()));
|
||||
}
|
||||
try {
|
||||
Double imbalance = ClusterDrsAlgorithm.getClusterImbalance(clusterId, cpuList, memoryList, null);
|
||||
@ -955,11 +944,8 @@ public class MetricsServiceImpl extends MutualExclusiveIdsManagerBase implements
|
||||
if (cluster == null) {
|
||||
continue;
|
||||
}
|
||||
for (final Host host: hostDao.findByClusterId(cluster.getId())) {
|
||||
if (host == null || host.getType() != Host.Type.Routing) {
|
||||
continue;
|
||||
}
|
||||
updateHostMetrics(hostMetrics, hostJoinDao.findById(host.getId()));
|
||||
for (final HostJoinVO host: hostJoinDao.findByClusterId(cluster.getId(), Host.Type.Routing)) {
|
||||
updateHostMetrics(hostMetrics, host);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
@ -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-03-13]
|
||||
|
||||
### Fixed
|
||||
|
||||
- Implemented missing delete datastore, to correctly cleanup on datastore removal
|
||||
|
||||
## [2025-02-21]
|
||||
|
||||
### Fixed
|
||||
|
||||
@ -286,7 +286,10 @@ public class LinstorPrimaryDataStoreLifeCycleImpl extends BasePrimaryDataStoreLi
|
||||
|
||||
@Override
|
||||
public boolean deleteDataStore(DataStore store) {
|
||||
return dataStoreHelper.deletePrimaryDataStore(store);
|
||||
if (cleanupDatastore(store)) {
|
||||
return dataStoreHelper.deletePrimaryDataStore(store);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
||||
@ -18,7 +18,6 @@
|
||||
*/
|
||||
package org.apache.cloudstack.storage.datastore.lifecycle;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URLDecoder;
|
||||
@ -30,6 +29,7 @@ import java.util.UUID;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import com.cloud.utils.StringUtils;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.HostScope;
|
||||
@ -48,8 +48,6 @@ import org.apache.cloudstack.storage.volume.datastore.PrimaryDataStoreHelper;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
|
||||
import com.cloud.agent.AgentManager;
|
||||
import com.cloud.agent.api.Answer;
|
||||
import com.cloud.agent.api.DeleteStoragePoolCommand;
|
||||
import com.cloud.agent.api.StoragePoolInfo;
|
||||
import com.cloud.capacity.CapacityManager;
|
||||
import com.cloud.dc.ClusterVO;
|
||||
@ -63,9 +61,6 @@ import com.cloud.storage.Storage;
|
||||
import com.cloud.storage.StorageManager;
|
||||
import com.cloud.storage.StoragePool;
|
||||
import com.cloud.storage.StoragePoolAutomation;
|
||||
import com.cloud.storage.StoragePoolHostVO;
|
||||
import com.cloud.storage.VMTemplateStoragePoolVO;
|
||||
import com.cloud.storage.VMTemplateStorageResourceAssoc;
|
||||
import com.cloud.storage.dao.StoragePoolHostDao;
|
||||
import com.cloud.template.TemplateManager;
|
||||
import com.cloud.utils.UriUtils;
|
||||
@ -111,7 +106,7 @@ public class ScaleIOPrimaryDataStoreLifeCycle extends BasePrimaryDataStoreLifeCy
|
||||
List<org.apache.cloudstack.storage.datastore.api.StoragePool> storagePools = client.listStoragePools();
|
||||
for (org.apache.cloudstack.storage.datastore.api.StoragePool pool : storagePools) {
|
||||
if (pool.getName().equals(storagePoolName)) {
|
||||
logger.info("Found PowerFlex storage pool: " + storagePoolName);
|
||||
logger.info("Found PowerFlex storage pool: {}", storagePoolName);
|
||||
final org.apache.cloudstack.storage.datastore.api.StoragePoolStatistics poolStatistics = client.getStoragePoolStatistics(pool.getId());
|
||||
pool.setStatistics(poolStatistics);
|
||||
|
||||
@ -164,7 +159,7 @@ public class ScaleIOPrimaryDataStoreLifeCycle extends BasePrimaryDataStoreLifeCy
|
||||
throw new CloudRuntimeException("Cluster Id must also be specified when the Pod Id is specified for Cluster-wide primary storage.");
|
||||
}
|
||||
|
||||
URI uri = null;
|
||||
URI uri;
|
||||
try {
|
||||
uri = new URI(UriUtils.encodeURIComponent(url));
|
||||
if (uri.getScheme() == null || !uri.getScheme().equalsIgnoreCase("powerflex")) {
|
||||
@ -174,12 +169,8 @@ public class ScaleIOPrimaryDataStoreLifeCycle extends BasePrimaryDataStoreLifeCy
|
||||
throw new InvalidParameterValueException(url + " is not a valid uri");
|
||||
}
|
||||
|
||||
String storagePoolName = null;
|
||||
try {
|
||||
storagePoolName = URLDecoder.decode(uri.getPath(), "UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
logger.error("[ignored] we are on a platform not supporting \"UTF-8\"!?!", e);
|
||||
}
|
||||
String storagePoolName;
|
||||
storagePoolName = URLDecoder.decode(uri.getPath(), StringUtils.getPreferredCharset());
|
||||
if (storagePoolName == null) { // if decoding fails, use getPath() anyway
|
||||
storagePoolName = uri.getPath();
|
||||
}
|
||||
@ -187,7 +178,7 @@ public class ScaleIOPrimaryDataStoreLifeCycle extends BasePrimaryDataStoreLifeCy
|
||||
|
||||
final String storageHost = uri.getHost();
|
||||
final int port = uri.getPort();
|
||||
String gatewayApiURL = null;
|
||||
String gatewayApiURL;
|
||||
if (port == -1) {
|
||||
gatewayApiURL = String.format("https://%s/api", storageHost);
|
||||
} else {
|
||||
@ -321,37 +312,11 @@ public class ScaleIOPrimaryDataStoreLifeCycle extends BasePrimaryDataStoreLifeCy
|
||||
|
||||
@Override
|
||||
public boolean deleteDataStore(DataStore dataStore) {
|
||||
StoragePool storagePool = (StoragePool)dataStore;
|
||||
StoragePoolVO storagePoolVO = primaryDataStoreDao.findById(storagePool.getId());
|
||||
if (storagePoolVO == null) {
|
||||
return false;
|
||||
if (cleanupDatastore(dataStore)) {
|
||||
ScaleIOGatewayClientConnectionPool.getInstance().removeClient(dataStore);
|
||||
return dataStoreHelper.deletePrimaryDataStore(dataStore);
|
||||
}
|
||||
|
||||
List<VMTemplateStoragePoolVO> unusedTemplatesInPool = templateMgr.getUnusedTemplatesInPool(storagePoolVO);
|
||||
for (VMTemplateStoragePoolVO templatePoolVO : unusedTemplatesInPool) {
|
||||
if (templatePoolVO.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) {
|
||||
templateMgr.evictTemplateFromStoragePool(templatePoolVO);
|
||||
}
|
||||
}
|
||||
|
||||
List<StoragePoolHostVO> poolHostVOs = storagePoolHostDao.listByPoolId(dataStore.getId());
|
||||
for (StoragePoolHostVO poolHostVO : poolHostVOs) {
|
||||
DeleteStoragePoolCommand deleteStoragePoolCommand = new DeleteStoragePoolCommand(storagePool);
|
||||
final Answer answer = agentMgr.easySend(poolHostVO.getHostId(), deleteStoragePoolCommand);
|
||||
if (answer != null && answer.getResult()) {
|
||||
logger.info("Successfully deleted storage pool: {} from host: {}", storagePool, poolHostVO.getHostId());
|
||||
} else {
|
||||
if (answer != null) {
|
||||
logger.error("Failed to delete storage pool: {} from host: {} , result: {}", storagePool, poolHostVO.getHostId(), answer.getResult());
|
||||
} else {
|
||||
logger.error("Failed to delete storage pool: {} from host: {}", storagePool, poolHostVO.getHostId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ScaleIOGatewayClientConnectionPool.getInstance().removeClient(dataStore);
|
||||
|
||||
return dataStoreHelper.deletePrimaryDataStore(dataStore);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -39,11 +39,11 @@ class sysConfigAgentFactory:
|
||||
return sysConfigAgentUbuntu(glbEnv)
|
||||
elif distribution == "CentOS" or distribution == "RHEL5":
|
||||
return sysConfigEL5(glbEnv)
|
||||
elif distribution == "Fedora" or distribution == "RHEL6":
|
||||
elif distribution == "RHEL6":
|
||||
return sysConfigEL6(glbEnv)
|
||||
elif distribution == "RHEL7":
|
||||
return sysConfigEL7(glbEnv)
|
||||
elif distribution in ["RHEL8", "RHEL9"]:
|
||||
elif distribution in ["Fedora", "RHEL8", "RHEL9", "RHEL10"]:
|
||||
return sysConfigEL(glbEnv)
|
||||
elif distribution == "SUSE":
|
||||
return sysConfigSUSE(glbEnv)
|
||||
@ -183,9 +183,10 @@ class sysConfigEL5(sysConfigAgentRedhatBase):
|
||||
networkConfigRedhat(self),
|
||||
libvirtConfigRedhat(self),
|
||||
firewallConfigAgent(self),
|
||||
nfsConfig(self),
|
||||
cloudAgentConfig(self)]
|
||||
|
||||
#it covers RHEL6/Fedora13/Fedora14
|
||||
#it covers RHEL6
|
||||
class sysConfigEL6(sysConfigAgentRedhatBase):
|
||||
def __init__(self, glbEnv):
|
||||
super(sysConfigEL6, self).__init__(glbEnv)
|
||||
|
||||
@ -124,6 +124,10 @@ class Distribution:
|
||||
version.find("Red Hat Enterprise Linux release 9") != -1 or version.find("Linux release 9.") != -1 or
|
||||
version.find("Linux release 9") != -1):
|
||||
self.distro = "RHEL9"
|
||||
elif (version.find("Red Hat Enterprise Linux Server release 10") != -1 or version.find("Scientific Linux release 10") != -1 or
|
||||
version.find("Red Hat Enterprise Linux release 10") != -1 or version.find("Linux release 10.") != -1 or
|
||||
version.find("Linux release 10") != -1):
|
||||
self.distro = "RHEL10"
|
||||
elif version.find("CentOS") != -1:
|
||||
self.distro = "CentOS"
|
||||
else:
|
||||
|
||||
@ -99,7 +99,7 @@ if [[ -f $destdir/template.properties ]]; then
|
||||
failed 2 "Data already exists at destination $destdir"
|
||||
fi
|
||||
|
||||
destfiles=$(find $destdir -name \*.$ext)
|
||||
destfiles=$(sudo find $destdir -name \*.$ext)
|
||||
if [[ "$destfiles" != "" ]]; then
|
||||
failed 2 "Data already exists at destination $destdir"
|
||||
fi
|
||||
@ -108,12 +108,12 @@ tmpfolder=/tmp/cloud/templates/
|
||||
mkdir -p $tmpfolder
|
||||
tmplfile=$tmpfolder/$localfile
|
||||
|
||||
sudo touch $tmplfile
|
||||
touch $tmplfile
|
||||
if [[ $? -ne 0 ]]; then
|
||||
failed 2 "Failed to create temporary file in directory $tmpfolder -- is it read-only or full?\n"
|
||||
fi
|
||||
|
||||
destcap=$(df -P $destdir | awk '{print $4}' | tail -1 )
|
||||
destcap=$(sudo df -P $destdir | awk '{print $4}' | tail -1 )
|
||||
[ $destcap -lt $DISKSPACE ] && echo "Insufficient free disk space for target folder $destdir: avail=${destcap}k req=${DISKSPACE}k" && failed 4
|
||||
|
||||
localcap=$(df -P $tmpfolder | awk '{print $4}' | tail -1 )
|
||||
@ -146,9 +146,9 @@ fi
|
||||
|
||||
|
||||
tmpltfile=$destdir/$localfile
|
||||
tmpltsize=$(ls -l $tmpltfile | awk -F" " '{print $5}')
|
||||
tmpltsize=$(sudo ls -l $tmpltfile | awk -F" " '{print $5}')
|
||||
if [[ "$ext" == "qcow2" ]]; then
|
||||
vrtmpltsize=$($qemuimgcmd info $tmpltfile | grep -i 'virtual size' | sed -ne 's/.*(\([0-9]*\).*/\1/p' | xargs)
|
||||
vrtmpltsize=$(sudo $qemuimgcmd info $tmpltfile | grep -i 'virtual size' | sed -ne 's/.*(\([0-9]*\).*/\1/p' | xargs)
|
||||
else
|
||||
vrtmpltsize=$tmpltsize
|
||||
fi
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
# The CloudStack management server needs sudo permissions
|
||||
# without a password.
|
||||
|
||||
Cmnd_Alias CLOUDSTACK = /bin/mkdir, /bin/mount, /bin/umount, /bin/cp, /bin/chmod, /usr/bin/keytool, /bin/keytool, /bin/touch
|
||||
Cmnd_Alias CLOUDSTACK = /bin/mkdir, /bin/mount, /bin/umount, /bin/cp, /bin/chmod, /usr/bin/keytool, /bin/keytool, /bin/touch, /bin/find, /bin/df, /bin/ls, /bin/qemu-img
|
||||
|
||||
Defaults:@MSUSER@ !requiretty
|
||||
|
||||
|
||||
@ -446,7 +446,9 @@ public class NetworkHelperImpl implements NetworkHelper {
|
||||
final int retryIndex = 5;
|
||||
final ExcludeList[] avoids = new ExcludeList[5];
|
||||
avoids[0] = new ExcludeList();
|
||||
avoids[0].addPod(routerToBeAvoid.getPodIdToDeployIn());
|
||||
if (routerToBeAvoid.getPodIdToDeployIn() != null) {
|
||||
avoids[0].addPod(routerToBeAvoid.getPodIdToDeployIn());
|
||||
}
|
||||
avoids[1] = new ExcludeList();
|
||||
avoids[1].addCluster(_hostDao.findById(routerToBeAvoid.getHostId()).getClusterId());
|
||||
avoids[2] = new ExcludeList();
|
||||
|
||||
@ -60,9 +60,10 @@ import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
||||
import org.apache.cloudstack.utils.identity.ManagementServerNode;
|
||||
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.cloud.agent.AgentManager;
|
||||
@ -92,7 +93,6 @@ import com.cloud.capacity.CapacityVO;
|
||||
import com.cloud.capacity.dao.CapacityDao;
|
||||
import com.cloud.cluster.ClusterManager;
|
||||
import com.cloud.configuration.Config;
|
||||
import com.cloud.configuration.ConfigurationManager;
|
||||
import com.cloud.cpu.CPU;
|
||||
import com.cloud.dc.ClusterDetailsDao;
|
||||
import com.cloud.dc.ClusterDetailsVO;
|
||||
@ -125,7 +125,6 @@ import com.cloud.exception.DiscoveryException;
|
||||
import com.cloud.exception.InsufficientServerCapacityException;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.exception.PermissionDeniedException;
|
||||
import com.cloud.exception.ResourceInUseException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.exception.StorageConflictException;
|
||||
import com.cloud.exception.StorageUnavailableException;
|
||||
@ -170,7 +169,6 @@ import com.cloud.storage.StorageService;
|
||||
import com.cloud.storage.VMTemplateVO;
|
||||
import com.cloud.storage.Volume;
|
||||
import com.cloud.storage.VolumeVO;
|
||||
import com.cloud.storage.dao.DiskOfferingDao;
|
||||
import com.cloud.storage.dao.GuestOSCategoryDao;
|
||||
import com.cloud.storage.dao.StoragePoolHostDao;
|
||||
import com.cloud.storage.dao.VMTemplateDao;
|
||||
@ -203,6 +201,7 @@ import com.cloud.utils.net.NetUtils;
|
||||
import com.cloud.utils.ssh.SSHCmdHelper;
|
||||
import com.cloud.utils.ssh.SshException;
|
||||
import com.cloud.vm.UserVmManager;
|
||||
import com.cloud.utils.StringUtils;
|
||||
import com.cloud.vm.VMInstanceVO;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.VirtualMachine.State;
|
||||
@ -236,8 +235,6 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
@Inject
|
||||
private CapacityDao _capacityDao;
|
||||
@Inject
|
||||
private DiskOfferingDao diskOfferingDao;
|
||||
@Inject
|
||||
private ServiceOfferingDao serviceOfferingDao;
|
||||
@Inject
|
||||
private HostDao _hostDao;
|
||||
@ -296,8 +293,6 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
@Inject
|
||||
private VMTemplateDao _templateDao;
|
||||
@Inject
|
||||
private ConfigurationManager _configMgr;
|
||||
@Inject
|
||||
private ClusterVSMMapDao _clusterVSMMapDao;
|
||||
@Inject
|
||||
private UserVmDetailsDao userVmDetailsDao;
|
||||
@ -312,9 +307,9 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
|
||||
private final long _nodeId = ManagementServerNode.getManagementServerId();
|
||||
|
||||
private final HashMap<String, ResourceStateAdapter> _resourceStateAdapters = new HashMap<String, ResourceStateAdapter>();
|
||||
private final HashMap<String, ResourceStateAdapter> _resourceStateAdapters = new HashMap<>();
|
||||
|
||||
private final HashMap<Integer, List<ResourceListener>> _lifeCycleListeners = new HashMap<Integer, List<ResourceListener>>();
|
||||
private final HashMap<Integer, List<ResourceListener>> _lifeCycleListeners = new HashMap<>();
|
||||
private HypervisorType _defaultSystemVMHypervisor;
|
||||
|
||||
private static final int ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION = 30; // seconds
|
||||
@ -324,11 +319,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
private SearchBuilder<HostGpuGroupsVO> _gpuAvailability;
|
||||
|
||||
private void insertListener(final Integer event, final ResourceListener listener) {
|
||||
List<ResourceListener> lst = _lifeCycleListeners.get(event);
|
||||
if (lst == null) {
|
||||
lst = new ArrayList<ResourceListener>();
|
||||
_lifeCycleListeners.put(event, lst);
|
||||
}
|
||||
List<ResourceListener> lst = _lifeCycleListeners.computeIfAbsent(event, k -> new ArrayList<>());
|
||||
|
||||
if (lst.contains(listener)) {
|
||||
throw new CloudRuntimeException("Duplicate resource lisener:" + listener.getClass().getSimpleName());
|
||||
@ -370,9 +361,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
@Override
|
||||
public void unregisterResourceEvent(final ResourceListener listener) {
|
||||
synchronized (_lifeCycleListeners) {
|
||||
final Iterator it = _lifeCycleListeners.entrySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
final Map.Entry<Integer, List<ResourceListener>> items = (Map.Entry<Integer, List<ResourceListener>>)it.next();
|
||||
for (Map.Entry<Integer, List<ResourceListener>> items : _lifeCycleListeners.entrySet()) {
|
||||
final List<ResourceListener> lst = items.getValue();
|
||||
lst.remove(listener);
|
||||
}
|
||||
@ -381,7 +370,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
|
||||
protected void processResourceEvent(final Integer event, final Object... params) {
|
||||
final List<ResourceListener> lst = _lifeCycleListeners.get(event);
|
||||
if (lst == null || lst.size() == 0) {
|
||||
if (lst == null || lst.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -422,7 +411,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
|
||||
@DB
|
||||
@Override
|
||||
public List<? extends Cluster> discoverCluster(final AddClusterCmd cmd) throws IllegalArgumentException, DiscoveryException, ResourceInUseException {
|
||||
public List<? extends Cluster> discoverCluster(final AddClusterCmd cmd) throws IllegalArgumentException, DiscoveryException {
|
||||
final long dcId = cmd.getZoneId();
|
||||
final long podId = cmd.getPodId();
|
||||
final String clusterName = cmd.getClusterName();
|
||||
@ -432,10 +421,10 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
CPU.CPUArch arch = cmd.getArch();
|
||||
|
||||
if (url != null) {
|
||||
url = URLDecoder.decode(url);
|
||||
url = URLDecoder.decode(url, com.cloud.utils.StringUtils.getPreferredCharset());
|
||||
}
|
||||
|
||||
URI uri = null;
|
||||
URI uri;
|
||||
|
||||
// Check if the zone exists in the system
|
||||
final DataCenterVO zone = _dcDao.findById(dcId);
|
||||
@ -519,7 +508,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
discoverer.putParam(allParams);
|
||||
}
|
||||
|
||||
final List<ClusterVO> result = new ArrayList<ClusterVO>();
|
||||
final List<ClusterVO> result = new ArrayList<>();
|
||||
|
||||
ClusterVO cluster = new ClusterVO(dcId, podId, clusterName);
|
||||
cluster.setHypervisorType(hypervisorType.toString());
|
||||
@ -540,7 +529,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
result.add(cluster);
|
||||
|
||||
if (clusterType == Cluster.ClusterType.CloudManaged) {
|
||||
final Map<String, String> details = new HashMap<String, String>();
|
||||
final Map<String, String> details = new HashMap<>();
|
||||
// should do this nicer perhaps ?
|
||||
if (hypervisorType == HypervisorType.Ovm3) {
|
||||
final Map<String, String> allParams = cmd.getFullUrlParams();
|
||||
@ -578,8 +567,8 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
throw new InvalidParameterValueException(url + " is not a valid uri");
|
||||
}
|
||||
|
||||
final List<HostVO> hosts = new ArrayList<HostVO>();
|
||||
Map<? extends ServerResource, Map<String, String>> resources = null;
|
||||
final List<HostVO> hosts = new ArrayList<>();
|
||||
Map<? extends ServerResource, Map<String, String>> resources;
|
||||
resources = discoverer.find(dcId, podId, cluster.getId(), uri, username, password, null);
|
||||
|
||||
if (resources != null) {
|
||||
@ -670,7 +659,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
private List<HostVO> discoverHostsFull(final Long dcId, final Long podId, Long clusterId, final String clusterName, String url, String username, String password,
|
||||
final String hypervisorType, final List<String> hostTags, final Map<String, String> params, final boolean deferAgentCreation) throws IllegalArgumentException, DiscoveryException,
|
||||
InvalidParameterValueException {
|
||||
URI uri = null;
|
||||
URI uri;
|
||||
|
||||
// Check if the zone exists in the system
|
||||
final DataCenterVO zone = _dcDao.findById(dcId);
|
||||
@ -810,7 +799,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
throw new InvalidParameterValueException(url + " is not a valid uri");
|
||||
}
|
||||
|
||||
final List<HostVO> hosts = new ArrayList<HostVO>();
|
||||
final List<HostVO> hosts = new ArrayList<>();
|
||||
logger.info("Trying to add a new host at {} in data center {}", url, zone);
|
||||
boolean isHypervisorTypeSupported = false;
|
||||
for (final Discoverer discoverer : _discoverers) {
|
||||
@ -872,7 +861,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
return null;
|
||||
}
|
||||
|
||||
HostVO host = null;
|
||||
HostVO host;
|
||||
if (deferAgentCreation) {
|
||||
host = (HostVO)createHostAndAgentDeferred(resource, entry.getValue(), true, hostTags, false);
|
||||
} else {
|
||||
@ -1099,7 +1088,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
// don't allow to remove the cluster if it has non-removed storage
|
||||
// pools
|
||||
final List<StoragePoolVO> storagePools = _storagePoolDao.listPoolsByCluster(cmd.getId());
|
||||
if (storagePools.size() > 0) {
|
||||
if (!storagePools.isEmpty()) {
|
||||
logger.debug("{} still has storage pools, can't remove", cluster);
|
||||
throw new CloudRuntimeException(String.format("Cluster: %s cannot be removed. Cluster still has storage pools", cluster));
|
||||
}
|
||||
@ -1166,7 +1155,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
}
|
||||
}
|
||||
|
||||
Cluster.ClusterType newClusterType = null;
|
||||
Cluster.ClusterType newClusterType;
|
||||
if (clusterType != null && !clusterType.isEmpty()) {
|
||||
try {
|
||||
newClusterType = Cluster.ClusterType.valueOf(clusterType);
|
||||
@ -1182,7 +1171,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
}
|
||||
}
|
||||
|
||||
Grouping.AllocationState newAllocationState = null;
|
||||
Grouping.AllocationState newAllocationState;
|
||||
if (allocationState != null && !allocationState.isEmpty()) {
|
||||
try {
|
||||
newAllocationState = Grouping.AllocationState.valueOf(allocationState);
|
||||
@ -1244,12 +1233,13 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
}
|
||||
}
|
||||
final int retry = 40;
|
||||
boolean lsuccess = true;
|
||||
boolean lsuccess;
|
||||
for (int i = 0; i < retry; i++) {
|
||||
lsuccess = true;
|
||||
try {
|
||||
Thread.sleep(5 * 1000);
|
||||
} catch (final Exception e) {
|
||||
Thread.currentThread().wait(5 * 1000);
|
||||
} catch (final InterruptedException e) {
|
||||
logger.debug("thread unexpectedly interrupted during wait, while updating cluster");
|
||||
}
|
||||
hosts = listAllUpAndEnabledHosts(Host.Type.Routing, cluster.getId(), cluster.getPodId(), cluster.getDataCenterId());
|
||||
for (final HostVO host : hosts) {
|
||||
@ -1258,12 +1248,12 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (lsuccess == true) {
|
||||
if (lsuccess) {
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (success == false) {
|
||||
if (!success) {
|
||||
throw new CloudRuntimeException("PrepareUnmanaged Failed due to some hosts are still in UP status after 5 Minutes, please try later ");
|
||||
}
|
||||
} finally {
|
||||
@ -1384,7 +1374,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
|
||||
/* TODO: move below to listener */
|
||||
if (host.getType() == Host.Type.Routing) {
|
||||
if (vms.size() == 0) {
|
||||
if (vms.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1412,7 +1402,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
String logMessage = String.format(
|
||||
"Unsupported host.maintenance.local.storage.strategy: %s. Please set a strategy according to the global settings description: "
|
||||
+ "'Error', 'Migration', or 'ForceStop'.",
|
||||
HOST_MAINTENANCE_LOCAL_STRATEGY.value().toString());
|
||||
HOST_MAINTENANCE_LOCAL_STRATEGY.value());
|
||||
logger.error(logMessage);
|
||||
throw new CloudRuntimeException("There are active VMs using the host's local storage pool. Please stop all VMs on this host that use local storage.");
|
||||
}
|
||||
@ -1469,14 +1459,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
ServiceOfferingVO offeringVO = serviceOfferingDao.findById(vm.getServiceOfferingId());
|
||||
final VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm, null, offeringVO, null, null);
|
||||
plan.setMigrationPlan(true);
|
||||
DeployDestination dest = null;
|
||||
DeploymentPlanner.ExcludeList avoids = new DeploymentPlanner.ExcludeList();
|
||||
avoids.addHost(host.getId());
|
||||
try {
|
||||
dest = deploymentManager.planDeployment(profile, plan, avoids, null);
|
||||
} catch (InsufficientServerCapacityException e) {
|
||||
throw new CloudRuntimeException(String.format("Maintenance failed, could not find deployment destination for VM: %s.", vm), e);
|
||||
}
|
||||
DeployDestination dest = getDeployDestination(vm, profile, plan, host);
|
||||
Host destHost = dest.getHost();
|
||||
|
||||
try {
|
||||
@ -1487,6 +1470,22 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
}
|
||||
}
|
||||
|
||||
private DeployDestination getDeployDestination(VMInstanceVO vm, VirtualMachineProfile profile, DataCenterDeployment plan, HostVO hostToAvoid) {
|
||||
DeployDestination dest;
|
||||
DeploymentPlanner.ExcludeList avoids = new DeploymentPlanner.ExcludeList();
|
||||
avoids.addHost(hostToAvoid.getId());
|
||||
try {
|
||||
dest = deploymentManager.planDeployment(profile, plan, avoids, null);
|
||||
} catch (InsufficientServerCapacityException e) {
|
||||
throw new CloudRuntimeException(String.format("Maintenance failed, could not find deployment destination for VM [id=%s, name=%s].", vm.getId(), vm.getInstanceName()),
|
||||
e);
|
||||
}
|
||||
if (dest == null) {
|
||||
throw new CloudRuntimeException(String.format("Maintenance failed, could not find deployment destination for VM [id=%s, name=%s], using plan: %s.", vm.getId(), vm.getInstanceName(), plan));
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean maintain(final long hostId) throws AgentUnavailableException {
|
||||
final Boolean result = propagateResourceEvent(hostId, ResourceState.Event.AdminAskMaintenance);
|
||||
@ -1535,15 +1534,15 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
|
||||
List<VMInstanceVO> migratingInVMs = _vmDao.findByHostInStates(hostId, State.Migrating);
|
||||
|
||||
if (migratingInVMs.size() > 0) {
|
||||
if (!migratingInVMs.isEmpty()) {
|
||||
throw new CloudRuntimeException("Host contains incoming VMs migrating. Please wait for them to complete before putting to maintenance.");
|
||||
}
|
||||
|
||||
if (_vmDao.findByHostInStates(hostId, State.Starting, State.Stopping).size() > 0) {
|
||||
if (!_vmDao.findByHostInStates(hostId, State.Starting, State.Stopping).isEmpty()) {
|
||||
throw new CloudRuntimeException("Host contains VMs in starting/stopping state. Please wait for them to complete before putting to maintenance.");
|
||||
}
|
||||
|
||||
if (_vmDao.findByHostInStates(hostId, State.Error, State.Unknown).size() > 0) {
|
||||
if (!_vmDao.findByHostInStates(hostId, State.Error, State.Unknown).isEmpty()) {
|
||||
throw new CloudRuntimeException("Host contains VMs in error/unknown/shutdown state. Please fix errors to proceed.");
|
||||
}
|
||||
|
||||
@ -1564,25 +1563,22 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
if(StringUtils.isBlank(HOST_MAINTENANCE_LOCAL_STRATEGY.value())) {
|
||||
return false;
|
||||
}
|
||||
return HOST_MAINTENANCE_LOCAL_STRATEGY.value().toLowerCase().equals(WorkType.Migration.toString().toLowerCase());
|
||||
return HOST_MAINTENANCE_LOCAL_STRATEGY.value().equalsIgnoreCase(WorkType.Migration.toString());
|
||||
}
|
||||
|
||||
protected boolean isMaintenanceLocalStrategyForceStop() {
|
||||
if(StringUtils.isBlank(HOST_MAINTENANCE_LOCAL_STRATEGY.value())) {
|
||||
return false;
|
||||
}
|
||||
return HOST_MAINTENANCE_LOCAL_STRATEGY.value().toLowerCase().equals(WorkType.ForceStop.toString().toLowerCase());
|
||||
return HOST_MAINTENANCE_LOCAL_STRATEGY.value().equalsIgnoreCase(WorkType.ForceStop.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the host.maintenance.local.storage.strategy is the Default: "Error", blank, empty, or null.
|
||||
*/
|
||||
protected boolean isMaintenanceLocalStrategyDefault() {
|
||||
if (StringUtils.isBlank(HOST_MAINTENANCE_LOCAL_STRATEGY.value().toString())
|
||||
|| HOST_MAINTENANCE_LOCAL_STRATEGY.value().toLowerCase().equals(State.Error.toString().toLowerCase())) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return StringUtils.isBlank(HOST_MAINTENANCE_LOCAL_STRATEGY.value())
|
||||
|| HOST_MAINTENANCE_LOCAL_STRATEGY.value().equalsIgnoreCase(State.Error.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1733,7 +1729,6 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
* Return true if host goes into Maintenance mode. There are various possibilities for VMs' states
|
||||
* on a host. We need to track the various VM states on each run and accordingly transit to the
|
||||
* appropriate state.
|
||||
*
|
||||
* We change states as follows -
|
||||
* 1. If there are no VMs in running, migrating, starting, stopping, error, unknown states we can move
|
||||
* to maintenance state. Note that there cannot be incoming migrations as the API Call prepare for
|
||||
@ -1907,7 +1902,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
guestOSDetail.setValue(String.valueOf(guestOSCategory.getId()));
|
||||
_hostDetailsDao.update(guestOSDetail.getId(), guestOSDetail);
|
||||
} else {
|
||||
final Map<String, String> detail = new HashMap<String, String>();
|
||||
final Map<String, String> detail = new HashMap<>();
|
||||
detail.put("guest.os.category.id", String.valueOf(guestOSCategory.getId()));
|
||||
_hostDetailsDao.persist(hostId, detail);
|
||||
}
|
||||
@ -2057,9 +2052,9 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
|
||||
@Override
|
||||
public List<HypervisorType> getSupportedHypervisorTypes(final long zoneId, final boolean forVirtualRouter, final Long podId) {
|
||||
final List<HypervisorType> hypervisorTypes = new ArrayList<HypervisorType>();
|
||||
final List<HypervisorType> hypervisorTypes = new ArrayList<>();
|
||||
|
||||
List<ClusterVO> clustersForZone = new ArrayList<ClusterVO>();
|
||||
List<ClusterVO> clustersForZone;
|
||||
if (podId != null) {
|
||||
clustersForZone = _clusterDao.listByPodId(podId);
|
||||
} else {
|
||||
@ -2068,7 +2063,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
|
||||
for (final ClusterVO cluster : clustersForZone) {
|
||||
final HypervisorType hType = cluster.getHypervisorType();
|
||||
if (!forVirtualRouter || forVirtualRouter && hType != HypervisorType.BareMetal && hType != HypervisorType.Ovm) {
|
||||
if (!forVirtualRouter || (hType != HypervisorType.BareMetal && hType != HypervisorType.Ovm)) {
|
||||
hypervisorTypes.add(hType);
|
||||
}
|
||||
}
|
||||
@ -2104,7 +2099,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
|
||||
if (isValid) {
|
||||
final List<ClusterVO> clusters = _clusterDao.listByDcHyType(zoneId, defaultHyper.toString());
|
||||
if (clusters.size() <= 0) {
|
||||
if (clusters.isEmpty()) {
|
||||
isValid = false;
|
||||
}
|
||||
}
|
||||
@ -2121,7 +2116,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
HypervisorType defaultHype = getDefaultHypervisor(zoneId);
|
||||
if (defaultHype == HypervisorType.None) {
|
||||
final List<HypervisorType> supportedHypes = getSupportedHypervisorTypes(zoneId, false, null);
|
||||
if (supportedHypes.size() > 0) {
|
||||
if (!supportedHypes.isEmpty()) {
|
||||
Collections.shuffle(supportedHypes);
|
||||
defaultHype = supportedHypes.get(0);
|
||||
}
|
||||
@ -2245,10 +2240,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
final String cidrNetmask = NetUtils.getCidrSubNet("255.255.255.255", cidrSize);
|
||||
final long cidrNetmaskNumeric = NetUtils.ip2Long(cidrNetmask);
|
||||
final long serverNetmaskNumeric = NetUtils.ip2Long(serverPrivateNetmask);
|
||||
if (serverNetmaskNumeric > cidrNetmaskNumeric) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return serverNetmaskNumeric <= cidrNetmaskNumeric;
|
||||
}
|
||||
|
||||
private HostVO getNewHost(StartupCommand[] startupCommands) {
|
||||
@ -2262,11 +2254,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
|
||||
host = findHostByGuid(startupCommand.getGuidWithoutResource());
|
||||
|
||||
if (host != null) {
|
||||
return host;
|
||||
}
|
||||
|
||||
return null;
|
||||
return host; // even when host == null!
|
||||
}
|
||||
|
||||
protected HostVO createHostVO(final StartupCommand[] cmds, final ServerResource resource, final Map<String, String> details, List<String> hostTags,
|
||||
@ -2297,11 +2285,11 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
}
|
||||
}
|
||||
|
||||
long dcId = -1;
|
||||
long dcId;
|
||||
DataCenterVO dc = _dcDao.findByName(dataCenter);
|
||||
if (dc == null) {
|
||||
try {
|
||||
dcId = Long.parseLong(dataCenter);
|
||||
dcId = Long.parseLong(dataCenter != null ? dataCenter : "-1");
|
||||
dc = _dcDao.findById(dcId);
|
||||
} catch (final NumberFormatException e) {
|
||||
logger.debug("Cannot parse " + dataCenter + " into Long.");
|
||||
@ -2315,7 +2303,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
HostPodVO p = _podDao.findByName(pod, dcId);
|
||||
if (p == null) {
|
||||
try {
|
||||
final long podId = Long.parseLong(pod);
|
||||
final long podId = Long.parseLong(pod != null ? pod : "-1");
|
||||
p = _podDao.findById(podId);
|
||||
} catch (final NumberFormatException e) {
|
||||
logger.debug("Cannot parse " + pod + " into Long.");
|
||||
@ -2334,9 +2322,9 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
clusterId = Long.valueOf(cluster);
|
||||
} catch (final NumberFormatException e) {
|
||||
if (podId != null) {
|
||||
ClusterVO c = _clusterDao.findBy(cluster, podId.longValue());
|
||||
ClusterVO c = _clusterDao.findBy(cluster, podId);
|
||||
if (c == null) {
|
||||
c = new ClusterVO(dcId, podId.longValue(), cluster);
|
||||
c = new ClusterVO(dcId, podId, cluster);
|
||||
c = _clusterDao.persist(c);
|
||||
}
|
||||
clusterId = c.getId();
|
||||
@ -2439,7 +2427,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
for (Long hostId : hostIds) {
|
||||
DetailVO hostDetailVO = _hostDetailsDao.findDetail(hostId, name);
|
||||
|
||||
if (hostDetailVO == null || Boolean.parseBoolean(hostDetailVO.getValue()) == false) {
|
||||
if (hostDetailVO == null || !Boolean.parseBoolean(hostDetailVO.getValue())) {
|
||||
clusterSupportsResigning = false;
|
||||
|
||||
break;
|
||||
@ -2531,7 +2519,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
new Request(-1l, -1l, cmds, true, false).logD("Startup request from directly connected host: ", true);
|
||||
new Request(-1L, -1L, cmds, true, false).logD("Startup request from directly connected host: ", true);
|
||||
}
|
||||
|
||||
if (old) {
|
||||
@ -2601,7 +2589,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
new Request(-1l, -1l, cmds, true, false).logD("Startup request from directly connected host: ", true);
|
||||
new Request(-1L, -1L, cmds, true, false).logD("Startup request from directly connected host: ", true);
|
||||
}
|
||||
|
||||
if (old) {
|
||||
@ -2702,8 +2690,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
throw new InvalidParameterValueException("Can't find zone with id " + zoneId);
|
||||
}
|
||||
|
||||
final Map<String, String> details = hostDetails;
|
||||
final String guid = details.get("guid");
|
||||
final String guid = hostDetails.get("guid");
|
||||
final List<HostVO> currentHosts = listAllUpAndEnabledHostsInOneZoneByType(hostType, zoneId);
|
||||
for (final HostVO currentHost : currentHosts) {
|
||||
if (currentHost.getGuid().equals(guid)) {
|
||||
@ -2719,7 +2706,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
return createHostVO(cmds, null, null, null, ResourceStateAdapter.Event.CREATE_HOST_VO_FOR_CONNECTED);
|
||||
}
|
||||
|
||||
private void checkIPConflicts(final HostPodVO pod, final DataCenterVO dc, final String serverPrivateIP, final String serverPrivateNetmask, final String serverPublicIP, final String serverPublicNetmask) {
|
||||
private void checkIPConflicts(final HostPodVO pod, final DataCenterVO dc, final String serverPrivateIP, final String serverPublicIP) {
|
||||
// If the server's private IP is the same as is public IP, this host has
|
||||
// a host-only private network. Don't check for conflicts with the
|
||||
// private IP address table.
|
||||
@ -2748,7 +2735,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
// If the server's public IP address is already in the database,
|
||||
// return false
|
||||
final List<IPAddressVO> existingPublicIPs = _publicIPAddressDao.listByDcIdIpAddress(dc.getId(), serverPublicIP);
|
||||
if (existingPublicIPs.size() > 0) {
|
||||
if (!existingPublicIPs.isEmpty()) {
|
||||
throw new IllegalArgumentException("The public ip address of the server (" + serverPublicIP + ") is already in use in zone: " + dc.getName());
|
||||
}
|
||||
}
|
||||
@ -2785,7 +2772,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
|
||||
final HostPodVO pod = _podDao.findById(host.getPodId());
|
||||
final DataCenterVO dc = _dcDao.findById(host.getDataCenterId());
|
||||
checkIPConflicts(pod, dc, ssCmd.getPrivateIpAddress(), ssCmd.getPublicIpAddress(), ssCmd.getPublicIpAddress(), ssCmd.getPublicNetmask());
|
||||
checkIPConflicts(pod, dc, ssCmd.getPrivateIpAddress(), ssCmd.getPublicIpAddress());
|
||||
host.setType(com.cloud.host.Host.Type.Routing);
|
||||
host.setDetails(details);
|
||||
host.setCaps(ssCmd.getCapabilities());
|
||||
@ -2823,8 +2810,8 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
throw new UnableDeleteHostException("Failed to set primary storage into maintenance mode");
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
logger.debug("Failed to set primary storage into maintenance mode, due to: " + e.toString());
|
||||
throw new UnableDeleteHostException("Failed to set primary storage into maintenance mode, due to: " + e.toString());
|
||||
logger.debug("Failed to set primary storage into maintenance mode", e);
|
||||
throw new UnableDeleteHostException("Failed to set primary storage into maintenance mode, due to: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2968,7 +2955,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
if (result.getReturnCode() != 0) {
|
||||
throw new CloudRuntimeException(String.format("Could not restart agent on %s due to: %s", host, result.getStdErr()));
|
||||
}
|
||||
logger.debug("cloudstack-agent restart result: " + result.toString());
|
||||
logger.debug("cloudstack-agent restart result: {}", result);
|
||||
} catch (final SshException e) {
|
||||
throw new CloudRuntimeException("SSH to agent is enabled, but agent restart failed", e);
|
||||
}
|
||||
@ -2989,7 +2976,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean executeUserRequest(final long hostId, final ResourceState.Event event) throws AgentUnavailableException {
|
||||
public boolean executeUserRequest(final long hostId, final ResourceState.Event event) {
|
||||
if (event == ResourceState.Event.AdminAskMaintenance) {
|
||||
return doMaintain(hostId);
|
||||
} else if (event == ResourceState.Event.AdminCancelMaintenance) {
|
||||
@ -3315,7 +3302,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
public HostStats getHostStatistics(final Host host) {
|
||||
final Answer answer = _agentMgr.easySend(host.getId(), new GetHostStatsCommand(host.getGuid(), host.getName(), host.getId()));
|
||||
|
||||
if (answer != null && answer instanceof UnsupportedAnswer) {
|
||||
if (answer instanceof UnsupportedAnswer) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -3351,20 +3338,16 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
@Override
|
||||
public String getHostTags(final long hostId) {
|
||||
final List<String> hostTags = _hostTagsDao.getHostTags(hostId).parallelStream().map(HostTagVO::getTag).collect(Collectors.toList());
|
||||
if (hostTags == null) {
|
||||
return null;
|
||||
} else {
|
||||
return com.cloud.utils.StringUtils.listToCsvTags(hostTags);
|
||||
}
|
||||
return StringUtils.listToCsvTags(hostTags);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PodCluster> listByDataCenter(final long dcId) {
|
||||
final List<HostPodVO> pods = _podDao.listByDataCenterId(dcId);
|
||||
final ArrayList<PodCluster> pcs = new ArrayList<PodCluster>();
|
||||
final ArrayList<PodCluster> pcs = new ArrayList<>();
|
||||
for (final HostPodVO pod : pods) {
|
||||
final List<ClusterVO> clusters = _clusterDao.listByPodId(pod.getId());
|
||||
if (clusters.size() == 0) {
|
||||
if (clusters.isEmpty()) {
|
||||
pcs.add(new PodCluster(pod, null));
|
||||
} else {
|
||||
for (final ClusterVO cluster : clusters) {
|
||||
@ -3409,7 +3392,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
public boolean isHostGpuEnabled(final long hostId) {
|
||||
final SearchCriteria<HostGpuGroupsVO> sc = _gpuAvailability.create();
|
||||
sc.setParameters("hostId", hostId);
|
||||
return _hostGpuGroupsDao.customSearch(sc, null).size() > 0 ? true : false;
|
||||
return !_hostGpuGroupsDao.customSearch(sc, null).isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -3474,7 +3457,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
// Update GPU group capacity
|
||||
final TransactionLegacy txn = TransactionLegacy.currentTxn();
|
||||
txn.start();
|
||||
_hostGpuGroupsDao.persist(hostId, new ArrayList<String>(groupDetails.keySet()));
|
||||
_hostGpuGroupsDao.persist(hostId, new ArrayList<>(groupDetails.keySet()));
|
||||
_vgpuTypesDao.persist(hostId, groupDetails);
|
||||
txn.commit();
|
||||
}
|
||||
@ -3482,7 +3465,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
@Override
|
||||
public HashMap<String, HashMap<String, VgpuTypesInfo>> getGPUStatistics(final HostVO host) {
|
||||
final Answer answer = _agentMgr.easySend(host.getId(), new GetGPUStatsCommand(host.getGuid(), host.getName()));
|
||||
if (answer != null && answer instanceof UnsupportedAnswer) {
|
||||
if (answer instanceof UnsupportedAnswer) {
|
||||
return null;
|
||||
}
|
||||
if (answer == null || !answer.getResult()) {
|
||||
@ -3523,7 +3506,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
||||
@ActionEvent(eventType = EventTypes.EVENT_HOST_RESERVATION_RELEASE, eventDescription = "releasing host reservation", async = true)
|
||||
public boolean releaseHostReservation(final Long hostId) {
|
||||
try {
|
||||
return Transaction.execute(new TransactionCallback<Boolean>() {
|
||||
return Transaction.execute(new TransactionCallback<>() {
|
||||
@Override
|
||||
public Boolean doInTransaction(final TransactionStatus status) {
|
||||
final PlannerHostReservationVO reservationEntry = _plannerHostReserveDao.findByHostId(hostId);
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
// under the License.
|
||||
package org.apache.cloudstack.storage.heuristics.presetvariables;
|
||||
|
||||
public class Domain extends GenericHeuristicPresetVariable{
|
||||
public class Domain extends GenericHeuristicPresetVariable {
|
||||
private String id;
|
||||
|
||||
public String getId() {
|
||||
|
||||
@ -36,10 +36,12 @@ public class GenericHeuristicPresetVariable {
|
||||
fieldNamesToIncludeInToString.add("name");
|
||||
}
|
||||
|
||||
/***
|
||||
* Converts the preset variable into a valid JSON object that will be injected into the JS interpreter.
|
||||
* This method should not be overridden or changed.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("GenericHeuristicPresetVariable %s",
|
||||
ReflectionToStringBuilderUtils.reflectOnlySelectedFields(
|
||||
this, fieldNamesToIncludeInToString.toArray(new String[0])));
|
||||
public final String toString() {
|
||||
return ReflectionToStringBuilderUtils.reflectOnlySelectedFields(this, fieldNamesToIncludeInToString.toArray(new String[0]));
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,46 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.cloudstack.storage.heuristics.presetvariables;
|
||||
|
||||
import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class AccountTest {
|
||||
|
||||
@Test
|
||||
public void toStringTestReturnsValidJson() {
|
||||
Account variable = new Account();
|
||||
variable.setName("test name");
|
||||
variable.setId("test id");
|
||||
|
||||
Domain domainVariable = new Domain();
|
||||
domainVariable.setId("domain id");
|
||||
domainVariable.setName("domain name");
|
||||
variable.setDomain(domainVariable);
|
||||
|
||||
String expected = ReflectionToStringBuilderUtils.reflectOnlySelectedFields(variable, "name", "id", "domain");
|
||||
String result = variable.toString();
|
||||
|
||||
Assert.assertEquals(expected, result);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,41 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.cloudstack.storage.heuristics.presetvariables;
|
||||
|
||||
import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class DomainTest {
|
||||
|
||||
@Test
|
||||
public void toStringTestReturnsValidJson() {
|
||||
Domain variable = new Domain();
|
||||
variable.setName("test name");
|
||||
variable.setId("test id");
|
||||
|
||||
String expected = ReflectionToStringBuilderUtils.reflectOnlySelectedFields(variable, "name", "id");
|
||||
String result = variable.toString();
|
||||
|
||||
Assert.assertEquals(expected, result);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,40 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.cloudstack.storage.heuristics.presetvariables;
|
||||
|
||||
import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class GenericHeuristicPresetVariableTest {
|
||||
|
||||
@Test
|
||||
public void toStringTestReturnsValidJson() {
|
||||
GenericHeuristicPresetVariable variable = new GenericHeuristicPresetVariable();
|
||||
variable.setName("test name");
|
||||
|
||||
String expected = ReflectionToStringBuilderUtils.reflectOnlySelectedFields(variable, "name");
|
||||
String result = variable.toString();
|
||||
|
||||
Assert.assertEquals(expected, result);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,45 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.cloudstack.storage.heuristics.presetvariables;
|
||||
|
||||
import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class SecondaryStorageTest {
|
||||
|
||||
@Test
|
||||
public void toStringTestReturnsValidJson() {
|
||||
SecondaryStorage variable = new SecondaryStorage();
|
||||
variable.setName("test name");
|
||||
variable.setId("test id");
|
||||
variable.setProtocol("test protocol");
|
||||
variable.setUsedDiskSize(1L);
|
||||
variable.setTotalDiskSize(2L);
|
||||
|
||||
String expected = ReflectionToStringBuilderUtils.reflectOnlySelectedFields(variable, "name", "id",
|
||||
"protocol", "usedDiskSize", "totalDiskSize");
|
||||
String result = variable.toString();
|
||||
|
||||
Assert.assertEquals(expected, result);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,44 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.cloudstack.storage.heuristics.presetvariables;
|
||||
|
||||
import com.cloud.hypervisor.Hypervisor;
|
||||
import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class SnapshotTest {
|
||||
|
||||
@Test
|
||||
public void toStringTestReturnsValidJson() {
|
||||
Snapshot variable = new Snapshot();
|
||||
variable.setName("test name");
|
||||
variable.setSize(1L);
|
||||
variable.setHypervisorType(Hypervisor.HypervisorType.KVM);
|
||||
|
||||
String expected = ReflectionToStringBuilderUtils.reflectOnlySelectedFields(variable, "name", "size",
|
||||
"hypervisorType");
|
||||
String result = variable.toString();
|
||||
|
||||
Assert.assertEquals(expected, result);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,46 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.cloudstack.storage.heuristics.presetvariables;
|
||||
|
||||
import com.cloud.hypervisor.Hypervisor;
|
||||
import com.cloud.storage.Storage;
|
||||
import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class TemplateTest {
|
||||
|
||||
@Test
|
||||
public void toStringTestReturnsValidJson() {
|
||||
Template variable = new Template();
|
||||
variable.setName("test name");
|
||||
variable.setTemplateType(Storage.TemplateType.USER);
|
||||
variable.setHypervisorType(Hypervisor.HypervisorType.KVM);
|
||||
variable.setFormat(Storage.ImageFormat.QCOW2);
|
||||
|
||||
String expected = ReflectionToStringBuilderUtils.reflectOnlySelectedFields(variable, "name", "templateType",
|
||||
"hypervisorType", "format");
|
||||
String result = variable.toString();
|
||||
|
||||
Assert.assertEquals(expected, result);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,44 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.cloudstack.storage.heuristics.presetvariables;
|
||||
|
||||
import com.cloud.storage.Storage;
|
||||
import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class VolumeTest {
|
||||
|
||||
@Test
|
||||
public void toStringTestReturnsValidJson() {
|
||||
Volume variable = new Volume();
|
||||
variable.setName("test name");
|
||||
variable.setFormat(Storage.ImageFormat.QCOW2);
|
||||
variable.setSize(1L);
|
||||
|
||||
String expected = ReflectionToStringBuilderUtils.reflectOnlySelectedFields(variable, "name", "format",
|
||||
"size");
|
||||
String result = variable.toString();
|
||||
|
||||
Assert.assertEquals(expected, result);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1069,7 +1069,7 @@ test_data = {
|
||||
"format": "raw",
|
||||
"hypervisor": "kvm",
|
||||
"ostype": "Other Linux (64-bit)",
|
||||
"url": "https://cloud-images.ubuntu.com/releases/22.04/release/ubuntu-22.04-server-cloudimg-amd64.img",
|
||||
"url": "https://cloud-images.ubuntu.com/releases/jammy/release/ubuntu-22.04-server-cloudimg-amd64.img",
|
||||
"requireshvm": "True",
|
||||
"ispublic": "True",
|
||||
"isextractable": "False"
|
||||
|
||||
@ -123,7 +123,7 @@ export default {
|
||||
dataView: true,
|
||||
groupAction: true,
|
||||
popup: true,
|
||||
groupMap: (selection, values) => { return selection.map(x => { return { id: x, considerlasthost: values.considerlasthost } }) },
|
||||
groupMap: (selection, values) => { return selection.map(x => { return { id: x, considerlasthost: values.considerlasthost === true } }) },
|
||||
args: (record, store) => {
|
||||
if (['Admin'].includes(store.userInfo.roletype)) {
|
||||
return ['considerlasthost']
|
||||
|
||||
@ -116,9 +116,14 @@ export default {
|
||||
label: 'label.disable.host',
|
||||
message: 'message.confirm.disable.host',
|
||||
dataView: true,
|
||||
show: (record) => { return record.resourcestate === 'Enabled' },
|
||||
show: (record) => record.resourcestate === 'Enabled',
|
||||
popup: true,
|
||||
component: shallowRef(defineAsyncComponent(() => import('@/views/infra/HostEnableDisable')))
|
||||
component: shallowRef(defineAsyncComponent(() => import('@/views/infra/HostEnableDisable'))),
|
||||
events: {
|
||||
'refresh-data': () => {
|
||||
store.dispatch('refreshCurrentPage')
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
api: 'updateHost',
|
||||
@ -126,9 +131,14 @@ export default {
|
||||
label: 'label.enable.host',
|
||||
message: 'message.confirm.enable.host',
|
||||
dataView: true,
|
||||
show: (record) => { return record.resourcestate === 'Disabled' },
|
||||
show: (record) => record.resourcestate === 'Disabled',
|
||||
popup: true,
|
||||
component: shallowRef(defineAsyncComponent(() => import('@/views/infra/HostEnableDisable')))
|
||||
component: shallowRef(defineAsyncComponent(() => import('@/views/infra/HostEnableDisable'))),
|
||||
events: {
|
||||
'refresh-data': () => {
|
||||
store.dispatch('refreshCurrentPage')
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
api: 'prepareHostForMaintenance',
|
||||
|
||||
@ -243,7 +243,7 @@ export default {
|
||||
id: this.resource.id
|
||||
}
|
||||
for (const key in values) {
|
||||
if (values[key]) {
|
||||
if (values[key] || values[key] === false) {
|
||||
params[key] = values[key]
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
<template>
|
||||
<div class="form-layout">
|
||||
<a-form
|
||||
:ref="formRef"
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="rules"
|
||||
@finish="handleSubmit"
|
||||
@ -54,7 +54,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, reactive, toRaw } from 'vue'
|
||||
import { reactive, toRaw } from 'vue'
|
||||
import { api } from '@/api'
|
||||
|
||||
export default {
|
||||
@ -78,11 +78,8 @@ export default {
|
||||
this.resourcestate = this.resource.resourcestate
|
||||
this.allocationstate = this.resourcestate === 'Enabled' ? 'Disable' : 'Enable'
|
||||
},
|
||||
beforeCreate () {
|
||||
},
|
||||
methods: {
|
||||
initForm () {
|
||||
this.formRef = ref()
|
||||
this.form = reactive({})
|
||||
this.rules = reactive({})
|
||||
},
|
||||
@ -97,11 +94,9 @@ export default {
|
||||
})
|
||||
},
|
||||
handleSubmit (e) {
|
||||
e.preventDefault()
|
||||
this.formRef.value.validate().then(() => {
|
||||
this.$refs.formRef.validate().then(() => {
|
||||
const values = toRaw(this.form)
|
||||
|
||||
var data = {
|
||||
const data = {
|
||||
allocationstate: this.allocationstate,
|
||||
id: this.resource.id
|
||||
}
|
||||
@ -110,24 +105,27 @@ export default {
|
||||
}
|
||||
api('updateHost', data).then(_ => {
|
||||
this.$emit('close-action')
|
||||
this.$emit('refresh-data')
|
||||
}).catch(err => {
|
||||
this.$message.error(err.message || 'Failed to update host status')
|
||||
})
|
||||
}).catch(() => {
|
||||
this.$message.error('Validation failed. Please check the inputs.')
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.reason {
|
||||
padding-top: 20px
|
||||
padding-top: 20px;
|
||||
}
|
||||
|
||||
.form-layout {
|
||||
width: 30vw;
|
||||
|
||||
@media (min-width: 500px) {
|
||||
width: 450px;
|
||||
}
|
||||
width: 30vw;
|
||||
@media (min-width: 500px) {
|
||||
width: 450px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -625,9 +625,9 @@ export default {
|
||||
if (this.publicLBExists && (idx === -1 || this.lbProviderMap.publicLb.vpc.indexOf(offering.service.map(svc => { return svc.provider[0].name })[idx]) === -1)) {
|
||||
filteredOfferings.push(offering)
|
||||
} else if (!this.publicLBExists && vpcLbServiceIndex > -1) {
|
||||
const vpcLbServiceProvider = vpcLbServiceIndex === -1 ? undefined : this.resource.service[vpcLbServiceIndex].provider[0].name
|
||||
const vpcLbServiceProviders = vpcLbServiceIndex === -1 ? undefined : this.resource.service[vpcLbServiceIndex].provider.map(provider => provider.name)
|
||||
const offeringLbServiceProvider = idx === -1 ? undefined : offering.service[idx].provider[0].name
|
||||
if (vpcLbServiceProvider && (!offeringLbServiceProvider || (offeringLbServiceProvider && vpcLbServiceProvider === offeringLbServiceProvider))) {
|
||||
if (vpcLbServiceProviders && (!offeringLbServiceProvider || (offeringLbServiceProvider && vpcLbServiceProviders.includes(offeringLbServiceProvider)))) {
|
||||
filteredOfferings.push(offering)
|
||||
}
|
||||
} else {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user