mirror of https://github.com/apache/cloudstack.git
Support for local data disk (part 2)
- Zone level config to enable/disable local storage usage for service and disk offerings. - Local storage gets discovered when a host is added/reconnected if zone level config is enabled. When disabled existing local storages are not removed but any new local storage is not added. - Deploy VM command validates service and disk offerings based on local storage config. - Upgrade uses the global config 'use.local.storage' to set the zone level config for local storage. Reviewed-by: Abhi, Nitin
This commit is contained in:
parent
ddcb3d7b30
commit
bb17d09e01
|
|
@ -288,6 +288,7 @@ public class ApiConstants {
|
|||
public static final String DHCP_RANGE = "dhcprange";
|
||||
public static final String UUID = "uuid";
|
||||
public static final String SECURITY_GROUP_EANBLED = "securitygroupenabled";
|
||||
public static final String LOCAL_STORAGE_EANBLED = "localstorageenabled";
|
||||
public static final String GUEST_IP_TYPE = "guestiptype";
|
||||
public static final String XEN_NETWORK_LABEL = "xennetworklabel";
|
||||
public static final String KVM_NETWORK_LABEL = "kvmnetworklabel";
|
||||
|
|
|
|||
|
|
@ -69,6 +69,9 @@ public class CreateZoneCmd extends BaseCmd {
|
|||
@Parameter(name=ApiConstants.SECURITY_GROUP_EANBLED, type=CommandType.BOOLEAN, description="true if network is security group enabled, false otherwise")
|
||||
private Boolean securitygroupenabled;
|
||||
|
||||
@Parameter(name=ApiConstants.LOCAL_STORAGE_EANBLED, type=CommandType.BOOLEAN, description="true if local storage offering enabled, false otherwise")
|
||||
private Boolean localStorageEnabled;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -119,8 +122,14 @@ public class CreateZoneCmd extends BaseCmd {
|
|||
}
|
||||
return securitygroupenabled;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public Boolean getLocalStorageEnabled() {
|
||||
if (localStorageEnabled == null) {
|
||||
return false;
|
||||
}
|
||||
return localStorageEnabled;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -372,13 +372,23 @@ public class DeployVMCmd extends BaseAsyncCreateCmd {
|
|||
throw new InvalidParameterValueException("Unable to use template " + templateId, null);
|
||||
}
|
||||
|
||||
DiskOffering diskOffering = null;
|
||||
if (diskOfferingId != null) {
|
||||
DiskOffering diskOffering = _configService.getDiskOffering(diskOfferingId);
|
||||
diskOffering = _configService.getDiskOffering(diskOfferingId);
|
||||
if (diskOffering == null) {
|
||||
throw new InvalidParameterValueException("Unable to find disk offering by id", null);
|
||||
}
|
||||
}
|
||||
|
||||
if (!zone.isLocalStorageEnabled()) {
|
||||
if (serviceOffering.getUseLocalStorage()) {
|
||||
throw new InvalidParameterValueException("Zone is not configured to use local storage but service offering " + serviceOffering.getName() + " uses it", null);
|
||||
}
|
||||
if (diskOffering != null && diskOffering.getUseLocalStorage()) {
|
||||
throw new InvalidParameterValueException("Zone is not configured to use local storage but disk offering " + diskOffering.getName() + " uses it", null);
|
||||
}
|
||||
}
|
||||
|
||||
UserVm vm = null;
|
||||
if (getHypervisor() == HypervisorType.BareMetal) {
|
||||
vm = _bareMetalVmService.createVirtualMachine(this);
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import com.cloud.api.IdentityMapper;
|
|||
import com.cloud.api.Implementation;
|
||||
import com.cloud.api.Parameter;
|
||||
import com.cloud.api.ServerApiException;
|
||||
import com.cloud.api.BaseCmd.CommandType;
|
||||
import com.cloud.api.response.ZoneResponse;
|
||||
import com.cloud.dc.DataCenter;
|
||||
import com.cloud.user.Account;
|
||||
|
|
@ -77,7 +78,10 @@ public class UpdateZoneCmd extends BaseCmd {
|
|||
|
||||
@Parameter(name=ApiConstants.DNS_SEARCH_ORDER, type=CommandType.LIST, collectionType = CommandType.STRING, description="the dns search order list")
|
||||
private List<String> dnsSearchOrder;
|
||||
|
||||
|
||||
@Parameter(name=ApiConstants.LOCAL_STORAGE_EANBLED, type=CommandType.BOOLEAN, description="true if local storage offering enabled, false otherwise")
|
||||
private Boolean localStorageEnabled;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -133,6 +137,14 @@ public class UpdateZoneCmd extends BaseCmd {
|
|||
public List<String> getDnsSearchOrder() {
|
||||
return dnsSearchOrder;
|
||||
}
|
||||
|
||||
public Boolean getLocalStorageEnabled() {
|
||||
if (localStorageEnabled == null) {
|
||||
return false;
|
||||
}
|
||||
return localStorageEnabled;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -82,6 +82,9 @@ public class ZoneResponse extends BaseResponse {
|
|||
@SerializedName("capacity") @Param(description="the capacity of the Zone", responseObject = CapacityResponse.class)
|
||||
private List<CapacityResponse> capacitites;
|
||||
|
||||
@SerializedName(ApiConstants.LOCAL_STORAGE_EANBLED) @Param(description="true if local storage offering enabled, false otherwise")
|
||||
private boolean localStorageEnabled;
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id.setValue(id);
|
||||
}
|
||||
|
|
@ -161,4 +164,8 @@ public class ZoneResponse extends BaseResponse {
|
|||
public void setDomainName(String domainName) {
|
||||
this.domainName = domainName;
|
||||
}
|
||||
|
||||
public void setLocalStorageEnabled(boolean localStorageEnabled) {
|
||||
this.localStorageEnabled = localStorageEnabled;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,4 +71,5 @@ public interface DataCenter extends Grouping {
|
|||
|
||||
String getZoneToken();
|
||||
|
||||
boolean isLocalStorageEnabled();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1017,6 +1017,7 @@ label.linklocal.ip=Link Local IP Adddress
|
|||
label.load.balancer=Load Balancer
|
||||
label.loading=Loading
|
||||
label.local=Local
|
||||
label.local.storage.enabled=Local Storage Enabled
|
||||
label.login=Login
|
||||
label.logout=Logout
|
||||
label.lun=LUN
|
||||
|
|
|
|||
|
|
@ -946,6 +946,7 @@ public class ApiResponseHelper implements ResponseGenerator {
|
|||
zoneResponse.setId(dataCenter.getId());
|
||||
zoneResponse.setName(dataCenter.getName());
|
||||
zoneResponse.setSecurityGroupsEnabled(ApiDBUtils.isSecurityGroupEnabledInZone(dataCenter.getId()));
|
||||
zoneResponse.setLocalStorageEnabled(dataCenter.isLocalStorageEnabled());
|
||||
|
||||
if ((dataCenter.getDescription() != null) && !dataCenter.getDescription().equalsIgnoreCase("null")) {
|
||||
zoneResponse.setDescription(dataCenter.getDescription());
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ public interface ConfigurationManager extends ConfigurationService, Manager {
|
|||
* @throws
|
||||
*/
|
||||
DataCenterVO createZone(long userId, String zoneName, String dns1, String dns2, String internalDns1, String internalDns2, String guestCidr, String domain, Long domainId, NetworkType zoneType, String allocationState,
|
||||
String networkDomain, boolean isSecurityGroupEnabled);
|
||||
String networkDomain, boolean isSecurityGroupEnabled, boolean isLocalStorageEnabled);
|
||||
|
||||
/**
|
||||
* Deletes a VLAN from the database, along with all of its IP addresses. Will not delete VLANs that have allocated
|
||||
|
|
|
|||
|
|
@ -1360,6 +1360,7 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura
|
|||
String dhcpProvider = cmd.getDhcpProvider();
|
||||
Map<?, ?> detailsMap = cmd.getDetails();
|
||||
String networkDomain = cmd.getDomain();
|
||||
Boolean localStorageEnabled = cmd.getLocalStorageEnabled();
|
||||
|
||||
Map<String, String> newDetails = new HashMap<String, String>();
|
||||
if (detailsMap != null) {
|
||||
|
|
@ -1466,6 +1467,9 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura
|
|||
zone.setInternalDns1(internalDns1);
|
||||
zone.setInternalDns2(internalDns2);
|
||||
zone.setGuestNetworkCidr(guestCidr);
|
||||
if (localStorageEnabled != null) {
|
||||
zone.setLocalStorageEnabled(localStorageEnabled.booleanValue());
|
||||
}
|
||||
|
||||
if (networkDomain != null) {
|
||||
if (networkDomain.isEmpty()) {
|
||||
|
|
@ -1539,7 +1543,7 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura
|
|||
@Override
|
||||
@DB
|
||||
public DataCenterVO createZone(long userId, String zoneName, String dns1, String dns2, String internalDns1, String internalDns2, String guestCidr, String domain, Long domainId,
|
||||
NetworkType zoneType, String allocationStateStr, String networkDomain, boolean isSecurityGroupEnabled) {
|
||||
NetworkType zoneType, String allocationStateStr, String networkDomain, boolean isSecurityGroupEnabled, boolean isLocalStorageEnabled) {
|
||||
|
||||
// checking the following params outside checkzoneparams method as we do
|
||||
// not use these params for updatezone
|
||||
|
|
@ -1565,7 +1569,7 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura
|
|||
try {
|
||||
txn.start();
|
||||
// Create the new zone in the database
|
||||
DataCenterVO zone = new DataCenterVO(zoneName, null, dns1, dns2, internalDns1, internalDns2, guestCidr, domain, domainId, zoneType, zoneToken, networkDomain, isSecurityGroupEnabled);
|
||||
DataCenterVO zone = new DataCenterVO(zoneName, null, dns1, dns2, internalDns1, internalDns2, guestCidr, domain, domainId, zoneType, zoneToken, networkDomain, isSecurityGroupEnabled, isLocalStorageEnabled);
|
||||
if (allocationStateStr != null && !allocationStateStr.isEmpty()) {
|
||||
Grouping.AllocationState allocationState = Grouping.AllocationState.valueOf(allocationStateStr);
|
||||
zone.setAllocationState(allocationState);
|
||||
|
|
@ -1645,6 +1649,7 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura
|
|||
String allocationState = cmd.getAllocationState();
|
||||
String networkDomain = cmd.getDomain();
|
||||
boolean isSecurityGroupEnabled = cmd.getSecuritygroupenabled();
|
||||
boolean isLocalStorageEnabled = cmd.getLocalStorageEnabled();
|
||||
|
||||
if (allocationState == null) {
|
||||
allocationState = Grouping.AllocationState.Disabled.toString();
|
||||
|
|
@ -1678,7 +1683,7 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura
|
|||
}
|
||||
|
||||
return createZone(userId, zoneName, dns1, dns2, internalDns1, internalDns2, guestCidr, domainVO != null ? domainVO.getName() : null, domainId, zoneType, allocationState, networkDomain,
|
||||
isSecurityGroupEnabled);
|
||||
isSecurityGroupEnabled, isLocalStorageEnabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -123,6 +123,9 @@ public class DataCenterVO implements DataCenter, Identity {
|
|||
@Column(name="is_security_group_enabled")
|
||||
boolean securityGroupEnabled;
|
||||
|
||||
@Column(name="is_local_storage_enabled")
|
||||
boolean localStorageEnabled;
|
||||
|
||||
@Override
|
||||
public String getDnsProvider() {
|
||||
return dnsProvider;
|
||||
|
|
@ -168,14 +171,14 @@ public class DataCenterVO implements DataCenter, Identity {
|
|||
this.firewallProvider = firewallProvider;
|
||||
}
|
||||
|
||||
public DataCenterVO(long id, String name, String description, String dns1, String dns2, String dns3, String dns4,String guestCidr, String domain, Long domainId, NetworkType zoneType, String zoneToken, String domainSuffix) {
|
||||
this(name, description, dns1, dns2, dns3, dns4, guestCidr, domain, domainId, zoneType, zoneToken, domainSuffix, false);
|
||||
public DataCenterVO(long id, String name, String description, String dns1, String dns2, String dns3, String dns4, String guestCidr, String domain, Long domainId, NetworkType zoneType, String zoneToken, String domainSuffix) {
|
||||
this(name, description, dns1, dns2, dns3, dns4, guestCidr, domain, domainId, zoneType, zoneToken, domainSuffix, false, false);
|
||||
this.id = id;
|
||||
this.allocationState = Grouping.AllocationState.Enabled;
|
||||
this.uuid = UUID.randomUUID().toString();
|
||||
}
|
||||
|
||||
public DataCenterVO(String name, String description, String dns1, String dns2, String dns3, String dns4, String guestCidr, String domain, Long domainId, NetworkType zoneType, String zoneToken, String domainSuffix, boolean securityGroupEnabled) {
|
||||
public DataCenterVO(String name, String description, String dns1, String dns2, String dns3, String dns4, String guestCidr, String domain, Long domainId, NetworkType zoneType, String zoneToken, String domainSuffix, boolean securityGroupEnabled, boolean localStorageEnabled) {
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.dns1 = dns1;
|
||||
|
|
@ -188,7 +191,7 @@ public class DataCenterVO implements DataCenter, Identity {
|
|||
this.networkType = zoneType;
|
||||
this.allocationState = Grouping.AllocationState.Enabled;
|
||||
this.securityGroupEnabled = securityGroupEnabled;
|
||||
|
||||
this.localStorageEnabled = localStorageEnabled;
|
||||
|
||||
if (zoneType == NetworkType.Advanced) {
|
||||
loadBalancerProvider = Provider.VirtualRouter.getName();
|
||||
|
|
@ -341,6 +344,15 @@ public class DataCenterVO implements DataCenter, Identity {
|
|||
this.securityGroupEnabled = enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLocalStorageEnabled() {
|
||||
return localStorageEnabled;
|
||||
}
|
||||
|
||||
public void setLocalStorageEnabled(boolean enabled) {
|
||||
this.localStorageEnabled = enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getDetails() {
|
||||
return details;
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@ import com.cloud.agent.api.StoragePoolInfo;
|
|||
import com.cloud.capacity.Capacity;
|
||||
import com.cloud.capacity.CapacityVO;
|
||||
import com.cloud.capacity.dao.CapacityDao;
|
||||
import com.cloud.dc.DataCenterVO;
|
||||
import com.cloud.dc.dao.DataCenterDao;
|
||||
import com.cloud.exception.ConnectionException;
|
||||
import com.cloud.host.HostVO;
|
||||
import com.cloud.host.Status;
|
||||
|
|
@ -43,6 +45,7 @@ public class LocalStoragePoolListener implements Listener {
|
|||
@Inject StoragePoolDao _storagePoolDao;
|
||||
@Inject StoragePoolHostDao _storagePoolHostDao;
|
||||
@Inject CapacityDao _capacityDao;
|
||||
@Inject DataCenterDao _dcDao;
|
||||
@Inject StorageManager _storageMgr;
|
||||
|
||||
@Override
|
||||
|
|
@ -83,6 +86,11 @@ public class LocalStoragePoolListener implements Listener {
|
|||
return;
|
||||
}
|
||||
|
||||
DataCenterVO dc = _dcDao.findById(host.getDataCenterId());
|
||||
if (dc == null || !dc.isLocalStorageEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
StoragePoolVO pool = _storagePoolDao.findPoolByHostPath(host.getDataCenterId(), host.getPodId(), pInfo.getHost(), pInfo.getHostPath(), pInfo.getUuid());
|
||||
if(pool == null && host.getHypervisorType() == HypervisorType.VMware) {
|
||||
|
|
|
|||
|
|
@ -959,10 +959,7 @@ public class StorageManagerImpl implements StorageManager, Manager, ClusterManag
|
|||
int wrks = NumbersUtil.parseInt(workers, 10);
|
||||
_executor = Executors.newScheduledThreadPool(wrks, new NamedThreadFactory("StorageManager-Scavenger"));
|
||||
|
||||
boolean localStorage = Boolean.parseBoolean(configs.get(Config.UseLocalStorage.key()));
|
||||
if (localStorage) {
|
||||
_agentMgr.registerForHostEvents(ComponentLocator.inject(LocalStoragePoolListener.class), true, false, false);
|
||||
}
|
||||
_agentMgr.registerForHostEvents(ComponentLocator.inject(LocalStoragePoolListener.class), true, false, false);
|
||||
|
||||
String maxVolumeSizeInGbString = configDao.getValue("storage.max.volume.size");
|
||||
_maxVolumeSizeInGb = NumbersUtil.parseLong(maxVolumeSizeInGbString, 2000);
|
||||
|
|
|
|||
|
|
@ -549,6 +549,7 @@ CREATE TABLE `cloud`.`data_center` (
|
|||
`allocation_state` varchar(32) NOT NULL DEFAULT 'Enabled' COMMENT 'Is this data center enabled for allocation for new resources',
|
||||
`zone_token` varchar(255),
|
||||
`is_security_group_enabled` tinyint NOT NULL DEFAULT 0 COMMENT '1: enabled, 0: not',
|
||||
`is_local_storage_enabled` tinyint NOT NULL DEFAULT 0 COMMENT 'Is local storage offering enabled for this data center; 1: enabled, 0: not',
|
||||
`removed` datetime COMMENT 'date removed if not null',
|
||||
PRIMARY KEY (`id`),
|
||||
CONSTRAINT `fk_data_center__domain_id` FOREIGN KEY (`domain_id`) REFERENCES `domain`(`id`),
|
||||
|
|
|
|||
|
|
@ -340,4 +340,5 @@ CREATE TABLE `cloud`.`s2s_vpn_connection` (
|
|||
CONSTRAINT `uc_s2s_vpn_connection__uuid` UNIQUE (`uuid`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
|
||||
ALTER TABLE `cloud`.`data_center` ADD COLUMN `is_local_storage_enabled` tinyint NOT NULL DEFAULT 0 COMMENT 'Is local storage offering enabled for this data center; 1: enabled, 0: not';
|
||||
UPDATE `cloud`.`data_center` SET `is_local_storage_enabled` = IF ((SELECT `value` FROM `cloud`.`configuration` WHERE `name`='use.local.storage')='true', 1, 0) WHERE `removed` IS NULL;
|
||||
|
|
|
|||
|
|
@ -2430,6 +2430,7 @@ dictionary = {
|
|||
'label.load.balancer': '<fmt:message key="label.load.balancer" />',
|
||||
'label.loading': '<fmt:message key="label.loading" />',
|
||||
'label.local': '<fmt:message key="label.local" />',
|
||||
'label.local.storage.enabled': '<fmt:message key="label.local.storage.enabled" />',
|
||||
'label.login': '<fmt:message key="label.login" />',
|
||||
'label.logout': '<fmt:message key="label.logout" />',
|
||||
'label.lun': '<fmt:message key="label.lun" />',
|
||||
|
|
|
|||
|
|
@ -3832,6 +3832,7 @@
|
|||
array1.push("&internaldns1=" + todb(args.data.internaldns1));
|
||||
array1.push("&internaldns2=" + todb(args.data.internaldns2)); //internaldns2 can be empty ("") when passed to API
|
||||
array1.push("&domain=" + todb(args.data.domain));
|
||||
array1.push("&localstorageenabled=" + todb(args.data.localstorageenabled));
|
||||
$.ajax({
|
||||
url: createURL("updateZone&id=" + args.context.physicalResources[0].id + array1.join("")),
|
||||
dataType: "json",
|
||||
|
|
@ -3875,6 +3876,16 @@
|
|||
domain: {
|
||||
label: 'label.network.domain',
|
||||
isEditable: true
|
||||
},
|
||||
localstorageenabled: {
|
||||
label: 'label.local.storage.enabled',
|
||||
converter: function(args) {
|
||||
if(args)
|
||||
return "true";
|
||||
else
|
||||
return "false";
|
||||
},
|
||||
isEditable: true
|
||||
}
|
||||
}
|
||||
],
|
||||
|
|
|
|||
Loading…
Reference in New Issue