Restrict existing strategies to their default scope
Diffrent stratege has diffrent default scope, restrict them to their default scope will avoid usage problems. 1)workload_balancing/thermal_optimization/airflow_optimization goals react on enabled nodes, so restrict default scope to compute nodes with up state and enabled status. 2)server_consolidation goal react on enabled or disabled nodes, So restrict default scope to compute nodes with up state and enabled/disabled status. Change-Id: I7437dee699ee2d3dd227a047196d4d8db811b81e Closes-Bug: #1714002
This commit is contained in:
@@ -197,6 +197,14 @@ class BasicConsolidation(base.ServerConsolidationBaseStrategy):
|
|||||||
def gnocchi(self, gnocchi):
|
def gnocchi(self, gnocchi):
|
||||||
self._gnocchi = gnocchi
|
self._gnocchi = gnocchi
|
||||||
|
|
||||||
|
def get_available_compute_nodes(self):
|
||||||
|
default_node_scope = [element.ServiceState.ENABLED.value,
|
||||||
|
element.ServiceState.DISABLED.value]
|
||||||
|
return {uuid: cn for uuid, cn in
|
||||||
|
self.compute_model.get_all_compute_nodes().items()
|
||||||
|
if cn.state == element.ServiceState.ONLINE.value and
|
||||||
|
cn.status in default_node_scope}
|
||||||
|
|
||||||
def check_migration(self, source_node, destination_node,
|
def check_migration(self, source_node, destination_node,
|
||||||
instance_to_migrate):
|
instance_to_migrate):
|
||||||
"""Check if the migration is possible
|
"""Check if the migration is possible
|
||||||
@@ -428,7 +436,7 @@ class BasicConsolidation(base.ServerConsolidationBaseStrategy):
|
|||||||
def compute_score_of_nodes(self):
|
def compute_score_of_nodes(self):
|
||||||
"""Calculate score of nodes based on load by VMs"""
|
"""Calculate score of nodes based on load by VMs"""
|
||||||
score = []
|
score = []
|
||||||
for node in self.compute_model.get_all_compute_nodes().values():
|
for node in self.get_available_compute_nodes().values():
|
||||||
if node.status == element.ServiceState.ENABLED.value:
|
if node.status == element.ServiceState.ENABLED.value:
|
||||||
self.number_of_enabled_nodes += 1
|
self.number_of_enabled_nodes += 1
|
||||||
|
|
||||||
@@ -502,7 +510,7 @@ class BasicConsolidation(base.ServerConsolidationBaseStrategy):
|
|||||||
if not self.compute_model:
|
if not self.compute_model:
|
||||||
raise exception.ClusterStateNotDefined()
|
raise exception.ClusterStateNotDefined()
|
||||||
|
|
||||||
if len(self.compute_model.get_all_compute_nodes()) == 0:
|
if len(self.get_available_compute_nodes()) == 0:
|
||||||
raise exception.ClusterEmpty()
|
raise exception.ClusterEmpty()
|
||||||
|
|
||||||
if self.compute_model.stale:
|
if self.compute_model.stale:
|
||||||
|
|||||||
@@ -171,6 +171,13 @@ class OutletTempControl(base.ThermalOptimizationBaseStrategy):
|
|||||||
choices=["ceilometer", "gnocchi"])
|
choices=["ceilometer", "gnocchi"])
|
||||||
]
|
]
|
||||||
|
|
||||||
|
def get_available_compute_nodes(self):
|
||||||
|
default_node_scope = [element.ServiceState.ENABLED.value]
|
||||||
|
return {uuid: cn for uuid, cn in
|
||||||
|
self.compute_model.get_all_compute_nodes().items()
|
||||||
|
if cn.state == element.ServiceState.ONLINE.value and
|
||||||
|
cn.status in default_node_scope}
|
||||||
|
|
||||||
def calc_used_resource(self, node):
|
def calc_used_resource(self, node):
|
||||||
"""Calculate the used vcpus, memory and disk based on VM flavors"""
|
"""Calculate the used vcpus, memory and disk based on VM flavors"""
|
||||||
instances = self.compute_model.get_node_instances(node)
|
instances = self.compute_model.get_node_instances(node)
|
||||||
@@ -186,7 +193,7 @@ class OutletTempControl(base.ThermalOptimizationBaseStrategy):
|
|||||||
|
|
||||||
def group_hosts_by_outlet_temp(self):
|
def group_hosts_by_outlet_temp(self):
|
||||||
"""Group hosts based on outlet temp meters"""
|
"""Group hosts based on outlet temp meters"""
|
||||||
nodes = self.compute_model.get_all_compute_nodes()
|
nodes = self.get_available_compute_nodes()
|
||||||
size_cluster = len(nodes)
|
size_cluster = len(nodes)
|
||||||
if size_cluster == 0:
|
if size_cluster == 0:
|
||||||
raise wexc.ClusterEmpty()
|
raise wexc.ClusterEmpty()
|
||||||
|
|||||||
@@ -214,6 +214,13 @@ class UniformAirflow(base.BaseStrategy):
|
|||||||
choices=["ceilometer", "gnocchi"])
|
choices=["ceilometer", "gnocchi"])
|
||||||
]
|
]
|
||||||
|
|
||||||
|
def get_available_compute_nodes(self):
|
||||||
|
default_node_scope = [element.ServiceState.ENABLED.value]
|
||||||
|
return {uuid: cn for uuid, cn in
|
||||||
|
self.compute_model.get_all_compute_nodes().items()
|
||||||
|
if cn.state == element.ServiceState.ONLINE.value and
|
||||||
|
cn.status in default_node_scope}
|
||||||
|
|
||||||
def calculate_used_resource(self, node):
|
def calculate_used_resource(self, node):
|
||||||
"""Compute the used vcpus, memory and disk based on instance flavors"""
|
"""Compute the used vcpus, memory and disk based on instance flavors"""
|
||||||
instances = self.compute_model.get_node_instances(node)
|
instances = self.compute_model.get_node_instances(node)
|
||||||
@@ -334,7 +341,7 @@ class UniformAirflow(base.BaseStrategy):
|
|||||||
def group_hosts_by_airflow(self):
|
def group_hosts_by_airflow(self):
|
||||||
"""Group hosts based on airflow meters"""
|
"""Group hosts based on airflow meters"""
|
||||||
|
|
||||||
nodes = self.compute_model.get_all_compute_nodes()
|
nodes = self.get_available_compute_nodes()
|
||||||
if not nodes:
|
if not nodes:
|
||||||
raise wexc.ClusterEmpty()
|
raise wexc.ClusterEmpty()
|
||||||
overload_hosts = []
|
overload_hosts = []
|
||||||
|
|||||||
20
watcher/decision_engine/strategy/strategies/vm_workload_consolidation.py
Executable file → Normal file
20
watcher/decision_engine/strategy/strategies/vm_workload_consolidation.py
Executable file → Normal file
@@ -169,6 +169,14 @@ class VMWorkloadConsolidation(base.ServerConsolidationBaseStrategy):
|
|||||||
choices=["ceilometer", "gnocchi"])
|
choices=["ceilometer", "gnocchi"])
|
||||||
]
|
]
|
||||||
|
|
||||||
|
def get_available_compute_nodes(self):
|
||||||
|
default_node_scope = [element.ServiceState.ENABLED.value,
|
||||||
|
element.ServiceState.DISABLED.value]
|
||||||
|
return {uuid: cn for uuid, cn in
|
||||||
|
self.compute_model.get_all_compute_nodes().items()
|
||||||
|
if cn.state == element.ServiceState.ONLINE.value and
|
||||||
|
cn.status in default_node_scope}
|
||||||
|
|
||||||
def get_instance_state_str(self, instance):
|
def get_instance_state_str(self, instance):
|
||||||
"""Get instance state in string format.
|
"""Get instance state in string format.
|
||||||
|
|
||||||
@@ -273,7 +281,7 @@ class VMWorkloadConsolidation(base.ServerConsolidationBaseStrategy):
|
|||||||
|
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
for node in self.compute_model.get_all_compute_nodes().values():
|
for node in self.get_available_compute_nodes().values():
|
||||||
if (len(self.compute_model.get_node_instances(node)) == 0 and
|
if (len(self.compute_model.get_node_instances(node)) == 0 and
|
||||||
node.status !=
|
node.status !=
|
||||||
element.ServiceState.DISABLED.value):
|
element.ServiceState.DISABLED.value):
|
||||||
@@ -422,7 +430,7 @@ class VMWorkloadConsolidation(base.ServerConsolidationBaseStrategy):
|
|||||||
RCU is an average of relative utilizations (rhu) of active nodes.
|
RCU is an average of relative utilizations (rhu) of active nodes.
|
||||||
:return: {'cpu': <0,1>, 'ram': <0,1>, 'disk': <0,1>}
|
:return: {'cpu': <0,1>, 'ram': <0,1>, 'disk': <0,1>}
|
||||||
"""
|
"""
|
||||||
nodes = self.compute_model.get_all_compute_nodes().values()
|
nodes = self.get_available_compute_nodes().values()
|
||||||
rcu = {}
|
rcu = {}
|
||||||
counters = {}
|
counters = {}
|
||||||
for node in nodes:
|
for node in nodes:
|
||||||
@@ -534,7 +542,7 @@ class VMWorkloadConsolidation(base.ServerConsolidationBaseStrategy):
|
|||||||
:param cc: dictionary containing resource capacity coefficients
|
:param cc: dictionary containing resource capacity coefficients
|
||||||
"""
|
"""
|
||||||
sorted_nodes = sorted(
|
sorted_nodes = sorted(
|
||||||
self.compute_model.get_all_compute_nodes().values(),
|
self.get_available_compute_nodes().values(),
|
||||||
key=lambda x: self.get_node_utilization(x)['cpu'])
|
key=lambda x: self.get_node_utilization(x)['cpu'])
|
||||||
for node in reversed(sorted_nodes):
|
for node in reversed(sorted_nodes):
|
||||||
if self.is_overloaded(node, cc):
|
if self.is_overloaded(node, cc):
|
||||||
@@ -567,7 +575,7 @@ class VMWorkloadConsolidation(base.ServerConsolidationBaseStrategy):
|
|||||||
:param cc: dictionary containing resource capacity coefficients
|
:param cc: dictionary containing resource capacity coefficients
|
||||||
"""
|
"""
|
||||||
sorted_nodes = sorted(
|
sorted_nodes = sorted(
|
||||||
self.compute_model.get_all_compute_nodes().values(),
|
self.get_available_compute_nodes().values(),
|
||||||
key=lambda x: self.get_node_utilization(x)['cpu'])
|
key=lambda x: self.get_node_utilization(x)['cpu'])
|
||||||
asc = 0
|
asc = 0
|
||||||
for node in sorted_nodes:
|
for node in sorted_nodes:
|
||||||
@@ -630,7 +638,7 @@ class VMWorkloadConsolidation(base.ServerConsolidationBaseStrategy):
|
|||||||
rcu_after = self.get_relative_cluster_utilization()
|
rcu_after = self.get_relative_cluster_utilization()
|
||||||
info = {
|
info = {
|
||||||
"compute_nodes_count": len(
|
"compute_nodes_count": len(
|
||||||
self.compute_model.get_all_compute_nodes()),
|
self.get_available_compute_nodes()),
|
||||||
'number_of_migrations': self.number_of_migrations,
|
'number_of_migrations': self.number_of_migrations,
|
||||||
'number_of_released_nodes':
|
'number_of_released_nodes':
|
||||||
self.number_of_released_nodes,
|
self.number_of_released_nodes,
|
||||||
@@ -643,7 +651,7 @@ class VMWorkloadConsolidation(base.ServerConsolidationBaseStrategy):
|
|||||||
def post_execute(self):
|
def post_execute(self):
|
||||||
self.solution.set_efficacy_indicators(
|
self.solution.set_efficacy_indicators(
|
||||||
compute_nodes_count=len(
|
compute_nodes_count=len(
|
||||||
self.compute_model.get_all_compute_nodes()),
|
self.get_available_compute_nodes()),
|
||||||
released_compute_nodes_count=self.number_of_released_nodes,
|
released_compute_nodes_count=self.number_of_released_nodes,
|
||||||
instance_migrations_count=self.number_of_migrations,
|
instance_migrations_count=self.number_of_migrations,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -180,6 +180,13 @@ class WorkloadBalance(base.WorkloadStabilizationBaseStrategy):
|
|||||||
choices=["ceilometer", "gnocchi"])
|
choices=["ceilometer", "gnocchi"])
|
||||||
]
|
]
|
||||||
|
|
||||||
|
def get_available_compute_nodes(self):
|
||||||
|
default_node_scope = [element.ServiceState.ENABLED.value]
|
||||||
|
return {uuid: cn for uuid, cn in
|
||||||
|
self.compute_model.get_all_compute_nodes().items()
|
||||||
|
if cn.state == element.ServiceState.ONLINE.value and
|
||||||
|
cn.status in default_node_scope}
|
||||||
|
|
||||||
def calculate_used_resource(self, node):
|
def calculate_used_resource(self, node):
|
||||||
"""Calculate the used vcpus, memory and disk based on VM flavors"""
|
"""Calculate the used vcpus, memory and disk based on VM flavors"""
|
||||||
instances = self.compute_model.get_node_instances(node)
|
instances = self.compute_model.get_node_instances(node)
|
||||||
@@ -271,7 +278,7 @@ class WorkloadBalance(base.WorkloadStabilizationBaseStrategy):
|
|||||||
and also generate the instance workload map.
|
and also generate the instance workload map.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
nodes = self.compute_model.get_all_compute_nodes()
|
nodes = self.get_available_compute_nodes()
|
||||||
cluster_size = len(nodes)
|
cluster_size = len(nodes)
|
||||||
if not nodes:
|
if not nodes:
|
||||||
raise wexc.ClusterEmpty()
|
raise wexc.ClusterEmpty()
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<ModelRoot>
|
<ModelRoot>
|
||||||
<ComputeNode hostname="hostname_0" uuid="Node_0" id="0" state="enabled" human_id="" status="enabled" vcpus="40" disk="250" disk_capacity="250" memory="64">
|
<ComputeNode hostname="hostname_0" uuid="Node_0" id="0" state="up" human_id="" status="enabled" vcpus="40" disk="250" disk_capacity="250" memory="64">
|
||||||
<Instance human_id="" state="active" uuid="INSTANCE_0" vcpus="10" disk="20" disk_capacity="20" memory="2" metadata='{"optimize": true,"top": "floor", "nested": {"x": "y"}}'/>
|
<Instance human_id="" state="active" uuid="INSTANCE_0" vcpus="10" disk="20" disk_capacity="20" memory="2" metadata='{"optimize": true,"top": "floor", "nested": {"x": "y"}}'/>
|
||||||
</ComputeNode>
|
</ComputeNode>
|
||||||
<ComputeNode hostname="hostname_1" uuid="Node_1" id="1" state="enabled" human_id="" status="enabled" vcpus="40" disk="250" disk_capacity="250" memory="64">
|
<ComputeNode hostname="hostname_1" uuid="Node_1" id="1" state="up" human_id="" status="enabled" vcpus="40" disk="250" disk_capacity="250" memory="64">
|
||||||
<Instance human_id="" state="active" uuid="INSTANCE_1" vcpus="10" disk="20" disk_capacity="20" memory="2" metadata='{"optimize": true,"top": "floor", "nested": {"x": "y"}}'/>
|
<Instance human_id="" state="active" uuid="INSTANCE_1" vcpus="10" disk="20" disk_capacity="20" memory="2" metadata='{"optimize": true,"top": "floor", "nested": {"x": "y"}}'/>
|
||||||
</ComputeNode>
|
</ComputeNode>
|
||||||
</ModelRoot>
|
</ModelRoot>
|
||||||
|
|||||||
Reference in New Issue
Block a user