diff --git a/api/src/com/cloud/api/ApiConstants.java b/api/src/com/cloud/api/ApiConstants.java index 0a666f32986..7f25c2d2f22 100755 --- a/api/src/com/cloud/api/ApiConstants.java +++ b/api/src/com/cloud/api/ApiConstants.java @@ -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"; diff --git a/api/src/com/cloud/api/commands/CreateZoneCmd.java b/api/src/com/cloud/api/commands/CreateZoneCmd.java index e06b342c72b..631abc6c831 100755 --- a/api/src/com/cloud/api/commands/CreateZoneCmd.java +++ b/api/src/com/cloud/api/commands/CreateZoneCmd.java @@ -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 diff --git a/api/src/com/cloud/api/commands/DeployVMCmd.java b/api/src/com/cloud/api/commands/DeployVMCmd.java index 29eb9063b89..fe43dcd99f5 100644 --- a/api/src/com/cloud/api/commands/DeployVMCmd.java +++ b/api/src/com/cloud/api/commands/DeployVMCmd.java @@ -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); diff --git a/api/src/com/cloud/api/commands/UpdateZoneCmd.java b/api/src/com/cloud/api/commands/UpdateZoneCmd.java index fae7f5a7238..0f4b6936ed2 100755 --- a/api/src/com/cloud/api/commands/UpdateZoneCmd.java +++ b/api/src/com/cloud/api/commands/UpdateZoneCmd.java @@ -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 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 getDnsSearchOrder() { return dnsSearchOrder; } + + public Boolean getLocalStorageEnabled() { + if (localStorageEnabled == null) { + return false; + } + return localStorageEnabled; + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// diff --git a/api/src/com/cloud/api/response/ZoneResponse.java b/api/src/com/cloud/api/response/ZoneResponse.java index 7a2aef7b79e..9db788ff368 100755 --- a/api/src/com/cloud/api/response/ZoneResponse.java +++ b/api/src/com/cloud/api/response/ZoneResponse.java @@ -82,6 +82,9 @@ public class ZoneResponse extends BaseResponse { @SerializedName("capacity") @Param(description="the capacity of the Zone", responseObject = CapacityResponse.class) private List 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; + } } diff --git a/api/src/com/cloud/dc/DataCenter.java b/api/src/com/cloud/dc/DataCenter.java index 0f3548cbe04..417b1b50460 100644 --- a/api/src/com/cloud/dc/DataCenter.java +++ b/api/src/com/cloud/dc/DataCenter.java @@ -71,4 +71,5 @@ public interface DataCenter extends Grouping { String getZoneToken(); + boolean isLocalStorageEnabled(); } diff --git a/client/WEB-INF/classes/resources/messages.properties b/client/WEB-INF/classes/resources/messages.properties index 84d11364eb9..beef22f4f8d 100644 --- a/client/WEB-INF/classes/resources/messages.properties +++ b/client/WEB-INF/classes/resources/messages.properties @@ -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 diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index 77d45c5971d..175baa6dfeb 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -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()); diff --git a/server/src/com/cloud/configuration/ConfigurationManager.java b/server/src/com/cloud/configuration/ConfigurationManager.java index 6e43895ad2d..9db92fe91ee 100644 --- a/server/src/com/cloud/configuration/ConfigurationManager.java +++ b/server/src/com/cloud/configuration/ConfigurationManager.java @@ -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 diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java index 191ebde33b8..f123a639e2c 100755 --- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java @@ -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 newDetails = new HashMap(); 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 diff --git a/server/src/com/cloud/dc/DataCenterVO.java b/server/src/com/cloud/dc/DataCenterVO.java index 14cb40fe2fe..731fe7b37cc 100644 --- a/server/src/com/cloud/dc/DataCenterVO.java +++ b/server/src/com/cloud/dc/DataCenterVO.java @@ -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 getDetails() { return details; diff --git a/server/src/com/cloud/storage/LocalStoragePoolListener.java b/server/src/com/cloud/storage/LocalStoragePoolListener.java index 73e9ca87a7f..11f45b5fd2f 100755 --- a/server/src/com/cloud/storage/LocalStoragePoolListener.java +++ b/server/src/com/cloud/storage/LocalStoragePoolListener.java @@ -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) { diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index f45e0ced711..545817e8da6 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -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); diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql index 9c6cea96387..a081749af9c 100755 --- a/setup/db/create-schema.sql +++ b/setup/db/create-schema.sql @@ -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`), diff --git a/setup/db/db/schema-304to305.sql b/setup/db/db/schema-304to305.sql index b1cc3c85bf8..29d79675fec 100755 --- a/setup/db/db/schema-304to305.sql +++ b/setup/db/db/schema-304to305.sql @@ -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; diff --git a/ui/index.jsp b/ui/index.jsp index cb9b4c6fd09..3cb2b6c5bcb 100644 --- a/ui/index.jsp +++ b/ui/index.jsp @@ -2430,6 +2430,7 @@ dictionary = { 'label.load.balancer': '', 'label.loading': '', 'label.local': '', +'label.local.storage.enabled': '', 'label.login': '', 'label.logout': '', 'label.lun': '', diff --git a/ui/scripts/system.js b/ui/scripts/system.js index 2f6fd844b55..c02ce1fa890 100644 --- a/ui/scripts/system.js +++ b/ui/scripts/system.js @@ -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 } } ],