Merge pull request #1457 from nvazquez/excludeclusters

CLOUDSTACK-9333: Exclude clusters from OVF operationsJIRA TICKET: https://issues.apache.org/jira/browse/CLOUDSTACK-9333

## Introduction
In some environments there is a need to exclude certain VMware clusters from performing OVF operations. This operations are part of:
* create template
* create volume snaphsot
* copy template, volume, images from primary storage to secondary storage
* migrate volume
* participate when a template gets cached over to primary storage.

In ESX/ESXi, OVF operations are low priority and bound to a single CPU and most likely get throttled to certain IOPS and network limits.
If the hypervisor chosen for OVF operations is weak or overloaded this results in significantly longer execution of such OVF command and therefore degraded performance of underlying CloudStack API call.

### Proposed solution
It is proposed to add a way to exclude hosts from selected clusters for OVF operations.
To exclude a cluster, would be necessary to insert a record in <code>cluster_details</code> specifying property **vmware.exclude_from_ovf** in this way: (supposing we want to exclude cluster X)

| cluster_id | name| value |
|:-------------:|:-------------:|:-------------:|
|X|vmware.exclude_from_ovf|true|

* pr/1457:
  CLOUDSTACK-9333: Exclude clusters for OVF operations

Signed-off-by: Will Stevens <williamstevens@gmail.com>
This commit is contained in:
Will Stevens 2016-04-07 13:30:20 -04:00
commit f960725dd5
4 changed files with 23 additions and 4 deletions

View File

@ -53,6 +53,16 @@ public interface CapacityManager {
"0.85", "0.85",
"Percentage (as a value between 0 and 1) of allocated storage utilization above which allocators will disable using the pool for low allocated storage available.", "Percentage (as a value between 0 and 1) of allocated storage utilization above which allocators will disable using the pool for low allocated storage available.",
true, ConfigKey.Scope.Zone); true, ConfigKey.Scope.Zone);
static final ConfigKey<Boolean> StorageOperationsExcludeCluster =
new ConfigKey<Boolean>(
Boolean.class,
"cluster.storage.operations.exclude",
"Advanced",
"false",
"Exclude cluster from storage operations",
true,
ConfigKey.Scope.Cluster,
null);
public boolean releaseVmCapacity(VirtualMachine vm, boolean moveFromReserved, boolean moveToReservered, Long hostId); public boolean releaseVmCapacity(VirtualMachine vm, boolean moveFromReserved, boolean moveToReservered, Long hostId);

View File

@ -44,6 +44,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
import org.apache.cloudstack.storage.LocalHostEndpoint; import org.apache.cloudstack.storage.LocalHostEndpoint;
import org.apache.cloudstack.storage.RemoteHostEndPoint; import org.apache.cloudstack.storage.RemoteHostEndPoint;
import com.cloud.capacity.CapacityManager;
import com.cloud.host.Host; import com.cloud.host.Host;
import com.cloud.host.HostVO; import com.cloud.host.HostVO;
import com.cloud.host.Status; import com.cloud.host.Status;
@ -64,9 +65,13 @@ public class DefaultEndPointSelector implements EndPointSelector {
private static final Logger s_logger = Logger.getLogger(DefaultEndPointSelector.class); private static final Logger s_logger = Logger.getLogger(DefaultEndPointSelector.class);
@Inject @Inject
HostDao hostDao; HostDao hostDao;
private final String findOneHostOnPrimaryStorage = private final String findOneHostOnPrimaryStorage = "select t.id from "
"select h.id from host h, storage_pool_host_ref s where h.status = 'Up' and h.type = 'Routing' and h.resource_state = 'Enabled' and" + "(select h.id, cd.value "
+ " h.id = s.host_id and s.pool_id = ? "; + "from host h join storage_pool_host_ref s on h.id = s.host_id "
+ "join cluster c on c.id=h.cluster_id "
+ "left join cluster_details cd on c.id=cd.cluster_id and cd.name='" + CapacityManager.StorageOperationsExcludeCluster.key() + "' "
+ "where h.status = 'Up' and h.type = 'Routing' and h.resource_state = 'Enabled' and s.pool_id = ? ";
private String findOneHypervisorHostInScope = "select h.id from host h where h.status = 'Up' and h.hypervisor_type is not null "; private String findOneHypervisorHostInScope = "select h.id from host h where h.status = 'Up' and h.hypervisor_type is not null ";
protected boolean moveBetweenPrimaryImage(DataStore srcStore, DataStore destStore) { protected boolean moveBetweenPrimaryImage(DataStore srcStore, DataStore destStore) {
@ -115,6 +120,7 @@ public class DefaultEndPointSelector implements EndPointSelector {
sbuilder.append(scope.getScopeId()); sbuilder.append(scope.getScopeId());
} }
// TODO: order by rand() is slow if there are lot of hosts // TODO: order by rand() is slow if there are lot of hosts
sbuilder.append(") t where t.value<>'true' or t.value is null"); //Added for exclude cluster's subquery
sbuilder.append(" ORDER by rand() limit 1"); sbuilder.append(" ORDER by rand() limit 1");
String sql = sbuilder.toString(); String sql = sbuilder.toString();
HostVO host = null; HostVO host = null;

View File

@ -1082,6 +1082,6 @@ public class CapacityManagerImpl extends ManagerBase implements CapacityManager,
@Override @Override
public ConfigKey<?>[] getConfigKeys() { public ConfigKey<?>[] getConfigKeys() {
return new ConfigKey<?>[] {CpuOverprovisioningFactor, MemOverprovisioningFactor, StorageCapacityDisableThreshold, StorageOverprovisioningFactor, return new ConfigKey<?>[] {CpuOverprovisioningFactor, MemOverprovisioningFactor, StorageCapacityDisableThreshold, StorageOverprovisioningFactor,
StorageAllocatedCapacityDisableThreshold}; StorageAllocatedCapacityDisableThreshold, StorageOperationsExcludeCluster};
} }
} }

View File

@ -410,3 +410,6 @@ VIEW `user_vm_view` AS
AND (`custom_speed`.`name` = 'CpuSpeed')))) AND (`custom_speed`.`name` = 'CpuSpeed'))))
LEFT JOIN `user_vm_details` `custom_ram_size` ON (((`custom_ram_size`.`vm_id` = `vm_instance`.`id`) LEFT JOIN `user_vm_details` `custom_ram_size` ON (((`custom_ram_size`.`vm_id` = `vm_instance`.`id`)
AND (`custom_ram_size`.`name` = 'memory')))); AND (`custom_ram_size`.`name` = 'memory'))));
-- Add cluster.storage.operations.exclude property
INSERT INTO `cloud`.`configuration` (`category`, `instance`, `component`, `name`, `description`, `default_value`, `updated`, `scope`, `is_dynamic`) VALUES ('Advanced', 'DEFAULT', 'CapacityManager', 'cluster.storage.operations.exclude', 'Exclude cluster from storage operations', 'false', now(), 'Cluster', '1');