Use disabled/enabled to change service state
The VM workload consolidation strategy sends 'down' instead of 'disabled' to change nova-compute service state. This patch will correct it. The same applies for enabling nova-compute service. Change-Id: I257411ef711b215bd9b56d0bf0479c79a9ef61d8 Closes-Bug: #1591901
This commit is contained in:
@@ -50,7 +50,7 @@ class VMWorkloadConsolidation(base.ServerConsolidationBaseStrategy):
|
|||||||
* Offload phase - handling over-utilized resources
|
* Offload phase - handling over-utilized resources
|
||||||
* Consolidation phase - handling under-utilized resources
|
* Consolidation phase - handling under-utilized resources
|
||||||
* Solution optimization - reducing number of migrations
|
* Solution optimization - reducing number of migrations
|
||||||
* Deactivation of unused hypervisors
|
* Disability of unused hypervisors
|
||||||
|
|
||||||
A capacity coefficients (cc) might be used to adjust optimization
|
A capacity coefficients (cc) might be used to adjust optimization
|
||||||
thresholds. Different resources may require different coefficient
|
thresholds. Different resources may require different coefficient
|
||||||
@@ -131,26 +131,26 @@ class VMWorkloadConsolidation(base.ServerConsolidationBaseStrategy):
|
|||||||
st=type(state))
|
st=type(state))
|
||||||
raise exception.WatcherException
|
raise exception.WatcherException
|
||||||
|
|
||||||
def add_action_activate_hypervisor(self, hypervisor):
|
def add_action_enable_hypervisor(self, hypervisor):
|
||||||
"""Add an action for hypervisor activation into the solution.
|
"""Add an action for hypervisor enabler into the solution.
|
||||||
|
|
||||||
:param hypervisor: hypervisor object
|
:param hypervisor: hypervisor object
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
params = {'state': hyper_state.HypervisorState.ONLINE.value}
|
params = {'state': hyper_state.HypervisorState.ENABLED.value}
|
||||||
self.solution.add_action(
|
self.solution.add_action(
|
||||||
action_type='change_nova_service_state',
|
action_type='change_nova_service_state',
|
||||||
resource_id=hypervisor.uuid,
|
resource_id=hypervisor.uuid,
|
||||||
input_parameters=params)
|
input_parameters=params)
|
||||||
self.number_of_released_hypervisors -= 1
|
self.number_of_released_hypervisors -= 1
|
||||||
|
|
||||||
def add_action_deactivate_hypervisor(self, hypervisor):
|
def add_action_disable_hypervisor(self, hypervisor):
|
||||||
"""Add an action for hypervisor deactivation into the solution.
|
"""Add an action for hypervisor disablity into the solution.
|
||||||
|
|
||||||
:param hypervisor: hypervisor object
|
:param hypervisor: hypervisor object
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
params = {'state': hyper_state.HypervisorState.OFFLINE.value}
|
params = {'state': hyper_state.HypervisorState.DISABLED.value}
|
||||||
self.solution.add_action(
|
self.solution.add_action(
|
||||||
action_type='change_nova_service_state',
|
action_type='change_nova_service_state',
|
||||||
resource_id=hypervisor.uuid,
|
resource_id=hypervisor.uuid,
|
||||||
@@ -184,8 +184,8 @@ class VMWorkloadConsolidation(base.ServerConsolidationBaseStrategy):
|
|||||||
migration_type = 'live'
|
migration_type = 'live'
|
||||||
|
|
||||||
dst_hyper_state_str = self.get_state_str(dst_hypervisor.state)
|
dst_hyper_state_str = self.get_state_str(dst_hypervisor.state)
|
||||||
if dst_hyper_state_str == hyper_state.HypervisorState.OFFLINE.value:
|
if dst_hyper_state_str == hyper_state.HypervisorState.DISABLED.value:
|
||||||
self.add_action_activate_hypervisor(dst_hypervisor)
|
self.add_action_enable_hypervisor(dst_hypervisor)
|
||||||
model.get_mapping().unmap(src_hypervisor, vm)
|
model.get_mapping().unmap(src_hypervisor, vm)
|
||||||
model.get_mapping().map(dst_hypervisor, vm)
|
model.get_mapping().map(dst_hypervisor, vm)
|
||||||
|
|
||||||
@@ -197,8 +197,8 @@ class VMWorkloadConsolidation(base.ServerConsolidationBaseStrategy):
|
|||||||
input_parameters=params)
|
input_parameters=params)
|
||||||
self.number_of_migrations += 1
|
self.number_of_migrations += 1
|
||||||
|
|
||||||
def deactivate_unused_hypervisors(self, model):
|
def disable_unused_hypervisors(self, model):
|
||||||
"""Generate actions for deactivation of unused hypervisors.
|
"""Generate actions for disablity of unused hypervisors.
|
||||||
|
|
||||||
:param model: model_root object
|
:param model: model_root object
|
||||||
:return: None
|
:return: None
|
||||||
@@ -207,7 +207,7 @@ class VMWorkloadConsolidation(base.ServerConsolidationBaseStrategy):
|
|||||||
if (len(model.get_mapping().get_node_vms(hypervisor)) == 0 and
|
if (len(model.get_mapping().get_node_vms(hypervisor)) == 0 and
|
||||||
hypervisor.status !=
|
hypervisor.status !=
|
||||||
hyper_state.HypervisorState.DISABLED.value):
|
hyper_state.HypervisorState.DISABLED.value):
|
||||||
self.add_action_deactivate_hypervisor(hypervisor)
|
self.add_action_disable_hypervisor(hypervisor)
|
||||||
|
|
||||||
def get_prediction_model(self):
|
def get_prediction_model(self):
|
||||||
"""Return a deepcopy of a model representing current cluster state.
|
"""Return a deepcopy of a model representing current cluster state.
|
||||||
@@ -339,7 +339,7 @@ class VMWorkloadConsolidation(base.ServerConsolidationBaseStrategy):
|
|||||||
counters = {}
|
counters = {}
|
||||||
for hypervisor in hypervisors:
|
for hypervisor in hypervisors:
|
||||||
hyper_state_str = self.get_state_str(hypervisor.state)
|
hyper_state_str = self.get_state_str(hypervisor.state)
|
||||||
if hyper_state_str == hyper_state.HypervisorState.ONLINE.value:
|
if hyper_state_str == hyper_state.HypervisorState.ENABLED.value:
|
||||||
rhu = self.get_relative_hypervisor_utilization(
|
rhu = self.get_relative_hypervisor_utilization(
|
||||||
hypervisor, model)
|
hypervisor, model)
|
||||||
for k in rhu.keys():
|
for k in rhu.keys():
|
||||||
@@ -437,12 +437,12 @@ class VMWorkloadConsolidation(base.ServerConsolidationBaseStrategy):
|
|||||||
the least CPU utilized VM first as live migration these
|
the least CPU utilized VM first as live migration these
|
||||||
generaly causes less troubles. This phase results in a cluster
|
generaly causes less troubles. This phase results in a cluster
|
||||||
with no overloaded hypervisors.
|
with no overloaded hypervisors.
|
||||||
* This phase is be able to activate turned off hypervisors (if needed
|
* This phase is be able to enable disabled hypervisors (if needed
|
||||||
and any available) in the case of the resource capacity provided by
|
and any available) in the case of the resource capacity provided by
|
||||||
active hypervisors is not able to accomodate all the load.
|
active hypervisors is not able to accomodate all the load.
|
||||||
As the offload phase is later followed by the consolidation phase,
|
As the offload phase is later followed by the consolidation phase,
|
||||||
the hypervisor activation in this phase doesn't necessarily results
|
the hypervisor enabler in this phase doesn't necessarily results
|
||||||
in more activated hypervisors in the final solution.
|
in more enabled hypervisors in the final solution.
|
||||||
|
|
||||||
:param model: model_root object
|
:param model: model_root object
|
||||||
:param cc: dictionary containing resource capacity coefficients
|
:param cc: dictionary containing resource capacity coefficients
|
||||||
@@ -514,7 +514,7 @@ class VMWorkloadConsolidation(base.ServerConsolidationBaseStrategy):
|
|||||||
* Offload phase - handling over-utilized resources
|
* Offload phase - handling over-utilized resources
|
||||||
* Consolidation phase - handling under-utilized resources
|
* Consolidation phase - handling under-utilized resources
|
||||||
* Solution optimization - reducing number of migrations
|
* Solution optimization - reducing number of migrations
|
||||||
* Deactivation of unused hypervisors
|
* Disability of unused hypervisors
|
||||||
|
|
||||||
:param original_model: root_model object
|
:param original_model: root_model object
|
||||||
"""
|
"""
|
||||||
@@ -534,8 +534,8 @@ class VMWorkloadConsolidation(base.ServerConsolidationBaseStrategy):
|
|||||||
# Optimize solution
|
# Optimize solution
|
||||||
self.optimize_solution(model)
|
self.optimize_solution(model)
|
||||||
|
|
||||||
# Deactivate unused hypervisors
|
# disable unused hypervisors
|
||||||
self.deactivate_unused_hypervisors(model)
|
self.disable_unused_hypervisors(model)
|
||||||
|
|
||||||
rcu_after = self.get_relative_cluster_utilization(model)
|
rcu_after = self.get_relative_cluster_utilization(model)
|
||||||
info = {
|
info = {
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ class FakerModelCollector(base.BaseClusterModelCollector):
|
|||||||
node = hypervisor.Hypervisor()
|
node = hypervisor.Hypervisor()
|
||||||
node.uuid = node_uuid
|
node.uuid = node_uuid
|
||||||
node.hostname = "hostname_{0}".format(i)
|
node.hostname = "hostname_{0}".format(i)
|
||||||
node.state = 'up'
|
node.state = 'enabled'
|
||||||
|
|
||||||
mem.set_capacity(node, 64)
|
mem.set_capacity(node, 64)
|
||||||
disk_capacity.set_capacity(node, 250)
|
disk_capacity.set_capacity(node, 250)
|
||||||
|
|||||||
@@ -149,44 +149,44 @@ class TestVMWorkloadConsolidation(base.BaseTestCase):
|
|||||||
res = self.strategy.vm_fits(vm_uuid, h, model, cc)
|
res = self.strategy.vm_fits(vm_uuid, h, model, cc)
|
||||||
self.assertEqual(False, res)
|
self.assertEqual(False, res)
|
||||||
|
|
||||||
def test_add_action_activate_hypervisor(self):
|
def test_add_action_enable_hypervisor(self):
|
||||||
model = self.fake_cluster.generate_scenario_1()
|
model = self.fake_cluster.generate_scenario_1()
|
||||||
self.m_model.return_value = model
|
self.m_model.return_value = model
|
||||||
self.fake_metrics.model = model
|
self.fake_metrics.model = model
|
||||||
h = model.get_hypervisor_from_id('Node_0')
|
h = model.get_hypervisor_from_id('Node_0')
|
||||||
self.strategy.add_action_activate_hypervisor(h)
|
self.strategy.add_action_enable_hypervisor(h)
|
||||||
expected = [{'action_type': 'change_nova_service_state',
|
expected = [{'action_type': 'change_nova_service_state',
|
||||||
'input_parameters': {'state': 'up',
|
'input_parameters': {'state': 'enabled',
|
||||||
'resource_id': 'Node_0'}}]
|
'resource_id': 'Node_0'}}]
|
||||||
self.assertEqual(expected, self.strategy.solution.actions)
|
self.assertEqual(expected, self.strategy.solution.actions)
|
||||||
|
|
||||||
def test_add_action_deactivate_hypervisor(self):
|
def test_add_action_disable_hypervisor(self):
|
||||||
model = self.fake_cluster.generate_scenario_1()
|
model = self.fake_cluster.generate_scenario_1()
|
||||||
self.m_model.return_value = model
|
self.m_model.return_value = model
|
||||||
self.fake_metrics.model = model
|
self.fake_metrics.model = model
|
||||||
h = model.get_hypervisor_from_id('Node_0')
|
h = model.get_hypervisor_from_id('Node_0')
|
||||||
self.strategy.add_action_deactivate_hypervisor(h)
|
self.strategy.add_action_disable_hypervisor(h)
|
||||||
expected = [{'action_type': 'change_nova_service_state',
|
expected = [{'action_type': 'change_nova_service_state',
|
||||||
'input_parameters': {'state': 'down',
|
'input_parameters': {'state': 'disabled',
|
||||||
'resource_id': 'Node_0'}}]
|
'resource_id': 'Node_0'}}]
|
||||||
self.assertEqual(expected, self.strategy.solution.actions)
|
self.assertEqual(expected, self.strategy.solution.actions)
|
||||||
|
|
||||||
def test_deactivate_unused_hypervisors(self):
|
def test_disable_unused_hypervisors(self):
|
||||||
model = self.fake_cluster.generate_scenario_1()
|
model = self.fake_cluster.generate_scenario_1()
|
||||||
self.m_model.return_value = model
|
self.m_model.return_value = model
|
||||||
self.fake_metrics.model = model
|
self.fake_metrics.model = model
|
||||||
h1 = model.get_hypervisor_from_id('Node_0')
|
h1 = model.get_hypervisor_from_id('Node_0')
|
||||||
h2 = model.get_hypervisor_from_id('Node_1')
|
h2 = model.get_hypervisor_from_id('Node_1')
|
||||||
vm_uuid = 'VM_0'
|
vm_uuid = 'VM_0'
|
||||||
self.strategy.deactivate_unused_hypervisors(model)
|
self.strategy.disable_unused_hypervisors(model)
|
||||||
self.assertEqual(0, len(self.strategy.solution.actions))
|
self.assertEqual(0, len(self.strategy.solution.actions))
|
||||||
|
|
||||||
# Migrate VM to free the hypervisor
|
# Migrate VM to free the hypervisor
|
||||||
self.strategy.add_migration(vm_uuid, h1, h2, model)
|
self.strategy.add_migration(vm_uuid, h1, h2, model)
|
||||||
|
|
||||||
self.strategy.deactivate_unused_hypervisors(model)
|
self.strategy.disable_unused_hypervisors(model)
|
||||||
expected = {'action_type': 'change_nova_service_state',
|
expected = {'action_type': 'change_nova_service_state',
|
||||||
'input_parameters': {'state': 'down',
|
'input_parameters': {'state': 'disabled',
|
||||||
'resource_id': 'Node_0'}}
|
'resource_id': 'Node_0'}}
|
||||||
self.assertEqual(2, len(self.strategy.solution.actions))
|
self.assertEqual(2, len(self.strategy.solution.actions))
|
||||||
self.assertEqual(expected, self.strategy.solution.actions[1])
|
self.assertEqual(expected, self.strategy.solution.actions[1])
|
||||||
|
|||||||
Reference in New Issue
Block a user