Add period input parameter to vm workload consolidation and

outlet temp control strategy.

Closes-Bug: #1614021
Change-Id: Iec975e4a4a39168a65ae89ca75a5ca9445c14f9d
This commit is contained in:
Santhosh Fernandes 2017-03-10 22:58:46 +05:30
parent ba98c88303
commit 377889859d
7 changed files with 87 additions and 12 deletions

View File

@ -72,6 +72,9 @@ Strategy parameter is:
parameter type default Value description
============== ====== ============= ====================================
``threshold`` Number 35.0 Temperature threshold for migration
``period`` Number 30 The time interval in seconds for
getting statistic aggregation from
metric data source
============== ====== ============= ====================================
Efficacy Indicator

View File

@ -70,6 +70,20 @@ Default Watcher's planner:
.. watcher-term:: watcher.decision_engine.planner.default.DefaultPlanner
Configuration
-------------
Strategy parameter is:
====================== ====== ============= ===================================
parameter type default Value description
====================== ====== ============= ===================================
``period`` Number 3600 The time interval in seconds
for getting statistic aggregation
from metric data source
====================== ====== ============= ===================================
Efficacy Indicator
------------------

View File

@ -98,6 +98,10 @@ class OutletTempControl(base.ThermalOptimizationBaseStrategy):
def get_translatable_display_name(cls):
return "Outlet temperature based strategy"
@property
def period(self):
return self.input_parameters.get('period', 30)
@classmethod
def get_schema(cls):
# Mandatory default setting for each element
@ -108,6 +112,12 @@ class OutletTempControl(base.ThermalOptimizationBaseStrategy):
"type": "number",
"default": 35.0
},
"period": {
"description": "The time interval in seconds for "
"getting statistic aggregation",
"type": "number",
"default": 30
},
},
}
@ -149,7 +159,7 @@ class OutletTempControl(base.ThermalOptimizationBaseStrategy):
outlet_temp = self.ceilometer.statistic_aggregation(
resource_id=resource_id,
meter_name=self._meter,
period="30",
period=self.period,
aggregate='avg')
# some hosts may not have outlet temp meters, remove from target
if outlet_temp is None:

View File

@ -87,6 +87,10 @@ class VMWorkloadConsolidation(base.ServerConsolidationBaseStrategy):
def get_translatable_display_name(cls):
return "VM Workload Consolidation Strategy"
@property
def period(self):
return self.input_parameters.get('period', 3600)
@property
def ceilometer(self):
if self._ceilometer is None:
@ -97,6 +101,20 @@ class VMWorkloadConsolidation(base.ServerConsolidationBaseStrategy):
def ceilometer(self, ceilometer):
self._ceilometer = ceilometer
@classmethod
def get_schema(cls):
# Mandatory default setting for each element
return {
"properties": {
"period": {
"description": "The time interval in seconds for "
"getting statistic aggregation",
"type": "number",
"default": 3600
}
}
}
def get_state_str(self, state):
"""Get resource state in string format.
@ -187,12 +205,10 @@ class VMWorkloadConsolidation(base.ServerConsolidationBaseStrategy):
element.ServiceState.DISABLED.value):
self.add_action_disable_node(node)
def get_instance_utilization(self, instance,
period=3600, aggr='avg'):
def get_instance_utilization(self, instance, aggr='avg'):
"""Collect cpu, ram and disk utilization statistics of a VM.
:param instance: instance object
:param period: seconds
:param aggr: string
:return: dict(cpu(number of vcpus used), ram(MB used), disk(B used))
"""
@ -206,7 +222,7 @@ class VMWorkloadConsolidation(base.ServerConsolidationBaseStrategy):
disk_alloc_metric = 'disk.root.size'
instance_cpu_util = self.ceilometer.statistic_aggregation(
resource_id=instance.uuid, meter_name=cpu_util_metric,
period=period, aggregate=aggr)
period=self.period, aggregate=aggr)
if instance_cpu_util:
total_cpu_utilization = (
@ -216,16 +232,16 @@ class VMWorkloadConsolidation(base.ServerConsolidationBaseStrategy):
instance_ram_util = self.ceilometer.statistic_aggregation(
resource_id=instance.uuid, meter_name=ram_util_metric,
period=period, aggregate=aggr)
period=self.period, aggregate=aggr)
if not instance_ram_util:
instance_ram_util = self.ceilometer.statistic_aggregation(
resource_id=instance.uuid, meter_name=ram_alloc_metric,
period=period, aggregate=aggr)
period=self.period, aggregate=aggr)
instance_disk_util = self.ceilometer.statistic_aggregation(
resource_id=instance.uuid, meter_name=disk_alloc_metric,
period=period, aggregate=aggr)
period=self.period, aggregate=aggr)
if not instance_ram_util or not instance_disk_util:
LOG.error(
@ -238,11 +254,10 @@ class VMWorkloadConsolidation(base.ServerConsolidationBaseStrategy):
disk=instance_disk_util)
return self.ceilometer_instance_data_cache.get(instance.uuid)
def get_node_utilization(self, node, period=3600, aggr='avg'):
def get_node_utilization(self, node, aggr='avg'):
"""Collect cpu, ram and disk utilization statistics of a node.
:param node: node object
:param period: seconds
:param aggr: string
:return: dict(cpu(number of cores used), ram(MB used), disk(B used))
"""
@ -252,7 +267,7 @@ class VMWorkloadConsolidation(base.ServerConsolidationBaseStrategy):
node_cpu_util = 0
for instance in node_instances:
instance_util = self.get_instance_utilization(
instance, period, aggr)
instance, aggr)
node_cpu_util += instance_util['cpu']
node_ram_util += instance_util['ram']
node_disk_util += instance_util['disk']

View File

@ -65,7 +65,7 @@ class FakeCeilometerMetrics(object):
mock['Node_1'] = 100
if uuid not in mock.keys():
mock[uuid] = 100
return mock[str(uuid)]
return float(mock[str(uuid)])
@staticmethod
def get_usage_node_ram(uuid):

View File

@ -151,3 +151,21 @@ class TestOutletTempControl(base.TestCase):
loaded_action = loader.load(action['action_type'])
loaded_action.input_parameters = action['input_parameters']
loaded_action.validate_parameters()
def test_periods(self):
model = self.fake_cluster.generate_scenario_3_with_2_nodes()
self.m_model.return_value = model
p_ceilometer = mock.patch.object(
strategies.OutletTempControl, "ceilometer")
m_ceilometer = p_ceilometer.start()
self.addCleanup(p_ceilometer.stop)
m_ceilometer.statistic_aggregation = mock.Mock(
side_effect=self.fake_metrics.mock_get_statistics)
node = model.get_node_by_uuid('Node_0')
self.strategy.input_parameters.update({'threshold': 35.0})
self.strategy.threshold = 35.0
self.strategy.group_hosts_by_outlet_temp()
m_ceilometer.statistic_aggregation.assert_any_call(
aggregate='avg',
meter_name='hardware.ipmi.node.outlet_temperature',
period=30, resource_id=node.uuid)

View File

@ -293,3 +293,18 @@ class TestVMWorkloadConsolidation(base.TestCase):
del expected[3]
del expected[1]
self.assertEqual(expected, self.strategy.solution.actions)
def test_periods(self):
model = self.fake_cluster.generate_scenario_1()
self.m_model.return_value = model
p_ceilometer = mock.patch.object(
strategies.VMWorkloadConsolidation, "ceilometer")
m_ceilometer = p_ceilometer.start()
self.addCleanup(p_ceilometer.stop)
m_ceilometer.return_value = mock.Mock(
statistic_aggregation=self.fake_metrics.mock_get_statistics)
instance0 = model.get_instance_by_uuid("INSTANCE_0")
self.strategy.get_instance_utilization(instance0)
m_ceilometer.statistic_aggregation.assert_any_call(
aggregate='avg', meter_name='disk.root.size',
period=3600, resource_id=instance0.uuid)