Merge "Rename Meta-Action to Action"

This commit is contained in:
Jenkins
2015-12-09 10:59:14 +00:00
committed by Gerrit Code Review
19 changed files with 137 additions and 200 deletions

View File

@@ -45,7 +45,7 @@ Here is an example showing how you can write a plugin called ``DummyStrategy``:
def execute(self, model): def execute(self, model):
self.solution.add_change_request( self.solution.add_change_request(
Migrate(vm=my_vm, source_hypervisor=src, dest_hypervisor=dest) Migrate(vm=my_vm, src_hypervisor=src, dest_hypervisor=dest)
) )
# Do some more stuff here ... # Do some more stuff here ...
return self.solution return self.solution

View File

@@ -23,7 +23,7 @@ from watcher.decision_engine.strategy.level import StrategyLevel
@six.add_metaclass(abc.ABCMeta) @six.add_metaclass(abc.ABCMeta)
class MetaAction(object): class BaseAction(object):
def __init__(self): def __init__(self):
self._level = StrategyLevel.conservative self._level = StrategyLevel.conservative
self._priority = 0 self._priority = 0
@@ -43,6 +43,3 @@ class MetaAction(object):
@priority.setter @priority.setter
def priority(self, p): def priority(self, p):
self._priority = p self._priority = p
def __str__(self):
return " "

View File

@@ -16,18 +16,17 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
# #
from watcher.decision_engine.meta_action.base import MetaAction from watcher.decision_engine.actions.base import BaseAction
from watcher.decision_engine.model.hypervisor_state import HypervisorState from watcher.decision_engine.model.hypervisor_state import HypervisorState
class ChangeHypervisorState(MetaAction): class ChangeHypervisorState(BaseAction):
def __init__(self, target): def __init__(self, target):
MetaAction.__init__(self) '''The target host to change the state
'''The target host to change the power
:param target: :param target: the target hypervisor uuid
:return:
''' '''
super(ChangeHypervisorState, self).__init__()
self._target = target self._target = target
self._state = HypervisorState.ONLINE self._state = HypervisorState.ONLINE
@@ -48,5 +47,5 @@ class ChangeHypervisorState(MetaAction):
self._target = p self._target = p
def __str__(self): def __str__(self):
return "{0} {1} ChangeHypervisorState => {2}".format( return "{} ChangeHypervisorState => {}".format(self.target,
MetaAction.__str__(self), self.target, self.state) self.state)

View File

@@ -0,0 +1,71 @@
# -*- encoding: utf-8 -*-
# Copyright (c) 2015 b<>com
#
# Authors: Jean-Emile DARTOIS <jean-emile.dartois@b-com.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
from enum import Enum
from watcher.decision_engine.actions.base import BaseAction
class MigrationType(Enum):
# Total migration time and downtime depend on memory dirtying speed
pre_copy = 0
# Postcopy transfer a page only once reliability
post_copy = 1
class Migrate(BaseAction):
def __init__(self, vm, src_hypervisor, dest_hypervisor):
"""Request to migrate a virtual machine from a host to another
:param vm: the virtual machine uuid to migrate
:param src_hypervisor: uuid
:param dest_hypervisor: uuid
"""
super(Migrate, self).__init__()
self._reserved_disk_iops = 0
self._remaining_dirty_pages = 0
self._vm = vm
self._migration_type = MigrationType.pre_copy
self._src_hypervisor = src_hypervisor
self._dest_hypervisor = dest_hypervisor
@property
def migration_type(self):
return self._migration_type
@migration_type.setter
def migration_type(self, type):
self._migration_type = type
@property
def vm(self):
return self._vm
@property
def src_hypervisor(self):
return self._src_hypervisor
@property
def dest_hypervisor(self):
return self._dest_hypervisor
def __str__(self):
return "Migrate {} from {} to {}".format(
self.vm,
self.src_hypervisor,
self.dest_hypervisor)

View File

@@ -17,9 +17,9 @@
# limitations under the License. # limitations under the License.
# #
from watcher.decision_engine.meta_action.base import MetaAction from watcher.decision_engine.actions.base import BaseAction
class Nop(MetaAction): class Nop(BaseAction):
def __str__(self): def __str__(self):
return "{0} Nop".format(MetaAction.__str__(self)) return "Nop"

View File

@@ -16,18 +16,17 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
# #
from watcher.decision_engine.meta_action.base import MetaAction from watcher.decision_engine.actions.base import BaseAction
from watcher.decision_engine.model.power_state import PowerState from watcher.decision_engine.model.power_state import PowerState
class ChangePowerState(MetaAction): class ChangePowerState(BaseAction):
def __init__(self, target): def __init__(self, target):
MetaAction.__init__(self)
"""The target host to change the power """The target host to change the power
:param target: :param target:
:return:
""" """
super(ChangePowerState, self).__init__()
self._target = target self._target = target
self._power_state = PowerState.g0 self._power_state = PowerState.g0
@@ -44,10 +43,9 @@ class ChangePowerState(MetaAction):
return self._target return self._target
@target.setter @target.setter
def target(self, p): def target(self, t):
self._target = p self._target = t
def __str__(self): def __str__(self):
return "{0} ChangePowerState {1} => {2} ".format( return "ChangePowerState {} => {} ".format(
MetaAction.__str__(self),
self.target, self.powerstate) self.target, self.powerstate)

View File

@@ -1,76 +0,0 @@
# -*- encoding: utf-8 -*-
# Copyright (c) 2015 b<>com
#
# Authors: Jean-Emile DARTOIS <jean-emile.dartois@b-com.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
from enum import Enum
from watcher.decision_engine.meta_action.base import MetaAction
class MigrationType(Enum):
# Total migration time and downtime depend on memory dirtying speed
pre_copy = 0
# Postcopy transfer a page only once reliability
post_copy = 1
class Migrate(MetaAction):
def __init__(self, vm, source_hypervisor, dest_hypervisor):
MetaAction.__init__(self)
"""Request Migrate
:param bandwidth the bandwidth reserved for the migration
:param vm: the virtual machine to migrate
:param source_hypervisor:
:param dest_hypervisor:
:return:
"""
self.bandwidth = 0
self.reservedDiskIOPS = 0
self.remainingDirtyPages = 0
self.vm = vm
self.migration_type = MigrationType.pre_copy
self.source_hypervisor = source_hypervisor
self.dest_hypervisor = dest_hypervisor
def set_migration_type(self, type):
self.migration_type = type
def set_bandwidth(self, bw):
"""Set the bandwidth reserved for the migration
:param bw: bandwidth
"""
self.bandwidth = bw
def get_bandwidth(self):
return self.bandwidth
def get_vm(self):
return self.vm
def get_source_hypervisor(self):
return self.source_hypervisor
def get_dest_hypervisor(self):
return self.dest_hypervisor
def __str__(self):
return "{0} Migrate {1} from {2} to {3}".format(
MetaAction.__str__(self), self.vm,
self.source_hypervisor,
self.dest_hypervisor)

View File

@@ -25,11 +25,11 @@ from watcher.decision_engine.planner.base import Planner
from watcher import objects from watcher import objects
from watcher.decision_engine.meta_action.hypervisor_state import \ from watcher.decision_engine.actions.hypervisor_state import \
ChangeHypervisorState ChangeHypervisorState
from watcher.decision_engine.meta_action.migrate import Migrate from watcher.decision_engine.actions.migration import Migrate
from watcher.decision_engine.meta_action.nop import Nop from watcher.decision_engine.actions.nop import Nop
from watcher.decision_engine.meta_action.power_state import ChangePowerState from watcher.decision_engine.actions.power_state import ChangePowerState
from watcher.objects.action import Status as AStatus from watcher.objects.action import Status as AStatus
from watcher.objects.action_plan import Status as APStatus from watcher.objects.action_plan import Status as APStatus
@@ -84,7 +84,7 @@ class DefaultPlanner(Planner):
LOG.debug('Create an action plan for the audit uuid') LOG.debug('Create an action plan for the audit uuid')
action_plan = self._create_action_plan(context, audit_id) action_plan = self._create_action_plan(context, audit_id)
actions = list(solution.meta_actions) actions = list(solution.actions)
to_schedule = [] to_schedule = []
for action in actions: for action in actions:
@@ -92,10 +92,10 @@ class DefaultPlanner(Planner):
# TODO(jed) type # TODO(jed) type
primitive = self.create_action(action_plan.id, primitive = self.create_action(action_plan.id,
Primitives.LIVE_MIGRATE.value, Primitives.LIVE_MIGRATE.value,
action.get_vm().uuid, action.vm.uuid,
action.get_source_hypervisor(). action.src_hypervisor.
uuid, uuid,
action.get_dest_hypervisor(). action.dest_hypervisor.
uuid, uuid,
description="{0}".format( description="{0}".format(
action) action)

View File

@@ -57,6 +57,6 @@ class Solution(object):
"Should have implemented this") # pragma:no cover "Should have implemented this") # pragma:no cover
@abc.abstractproperty @abc.abstractproperty
def meta_actions(self): def actions(self):
raise NotImplementedError( raise NotImplementedError(
"Should have implemented this") # pragma:no cover "Should have implemented this") # pragma:no cover

View File

@@ -24,20 +24,21 @@ LOG = log.getLogger(__name__)
class DefaultSolution(Solution): class DefaultSolution(Solution):
def __init__(self): def __init__(self):
self._meta_actions = [] """The DefaultSolution class store a set of actions generated by a
strategy in order to achieve the goal.
def add_change_request(self, r):
self._meta_actions.append(r)
def __str__(self):
val = ""
for action in self._meta_actions:
val += str(action) + "\n"
return val
@property
def meta_actions(self):
"""Get the current meta-actions of the solution
""" """
return self._meta_actions super(DefaultSolution, self).__init__()
self._actions = []
def add_change_request(self, r):
self._actions.append(r)
def __str__(self):
return "\n".join(self._actions)
@property
def actions(self):
"""Get the current actions of the solution
"""
return self._actions

View File

@@ -17,21 +17,19 @@
# limitations under the License. # limitations under the License.
# #
from oslo_log import log from oslo_log import log
from watcher.common.exception import ClusterEmpty from watcher.common.exception import ClusterEmpty
from watcher.common.exception import ClusteStateNotDefined from watcher.common.exception import ClusteStateNotDefined
from watcher.decision_engine.strategy.base import BaseStrategy from watcher.decision_engine.actions.hypervisor_state import \
from watcher.decision_engine.strategy.level import StrategyLevel
from watcher.decision_engine.meta_action.hypervisor_state import \
ChangeHypervisorState ChangeHypervisorState
from watcher.decision_engine.meta_action.migrate import Migrate from watcher.decision_engine.actions.migration import Migrate
from watcher.decision_engine.meta_action.migrate import MigrationType from watcher.decision_engine.actions.migration import MigrationType
from watcher.decision_engine.meta_action.power_state import ChangePowerState from watcher.decision_engine.actions.power_state import ChangePowerState
from watcher.decision_engine.meta_action.power_state import PowerState
from watcher.decision_engine.model.hypervisor_state import HypervisorState from watcher.decision_engine.model.hypervisor_state import HypervisorState
from watcher.decision_engine.model.power_state import PowerState
from watcher.decision_engine.model.resource import ResourceType from watcher.decision_engine.model.resource import ResourceType
from watcher.decision_engine.model.vm_state import VMState from watcher.decision_engine.model.vm_state import VMState
from watcher.decision_engine.strategy.base import BaseStrategy
from watcher.decision_engine.strategy.level import StrategyLevel
from watcher.metrics_engine.cluster_history.ceilometer import \ from watcher.metrics_engine.cluster_history.ceilometer import \
CeilometerClusterHistory CeilometerClusterHistory
@@ -39,7 +37,6 @@ LOG = log.getLogger(__name__)
class BasicConsolidation(BaseStrategy): class BasicConsolidation(BaseStrategy):
DEFAULT_NAME = "basic" DEFAULT_NAME = "basic"
DEFAULT_DESCRIPTION = "Basic offline consolidation" DEFAULT_DESCRIPTION = "Basic offline consolidation"
@@ -447,8 +444,8 @@ class BasicConsolidation(BaseStrategy):
mig_src_hypervisor, mig_src_hypervisor,
mig_dst_hypervisor) mig_dst_hypervisor)
# live migration # live migration
live_migrate.set_migration_type( live_migrate.migration_type = \
MigrationType.pre_copy) MigrationType.pre_copy
live_migrate.level = StrategyLevel.conservative live_migrate.level = StrategyLevel.conservative
tmp_vm_migration_schedule.append(live_migrate) tmp_vm_migration_schedule.append(live_migrate)

View File

@@ -18,7 +18,7 @@
# #
from oslo_log import log from oslo_log import log
from watcher.decision_engine.meta_action.nop import Nop from watcher.decision_engine.actions.nop import Nop
from watcher.decision_engine.strategy.base import BaseStrategy from watcher.decision_engine.strategy.base import BaseStrategy
LOG = log.getLogger(__name__) LOG = log.getLogger(__name__)

View File

@@ -1,32 +0,0 @@
# -*- encoding: utf-8 -*-
# Copyright (c) 2015 b<>com
#
# Authors: Jean-Emile DARTOIS <jean-emile.dartois@b-com.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
from watcher.decision_engine.meta_action.migrate import Migrate
from watcher.decision_engine.model.hypervisor import Hypervisor
from watcher.decision_engine.model.vm import VM
from watcher.tests import base
class TestMigtrate(base.BaseTestCase):
def test_set_get_bandwidth(self):
vm = VM()
hyp_src = Hypervisor()
hyp_dst = Hypervisor()
mig = Migrate(vm, hyp_src, hyp_dst)
mig.set_bandwidth(2)
self.assertEqual(mig.get_bandwidth(), 2)

View File

@@ -14,17 +14,17 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
from watcher.decision_engine.meta_action.base import MetaAction from watcher.decision_engine.actions.base import BaseAction
from watcher.tests import base from watcher.tests import base
class TestMetaAction(base.TestCase): class TestAction(base.TestCase):
def test_get_priority(self): def test_get_priority(self):
ma = MetaAction() ma = BaseAction()
ma.priority = 3 ma.priority = 3
self.assertEqual(ma.priority, 3) self.assertEqual(ma.priority, 3)
def test_get_level(self): def test_get_level(self):
ma = MetaAction() ma = BaseAction()
ma.level = 5 ma.level = 5
self.assertEqual(ma.level, 5) self.assertEqual(ma.level, 5)

View File

@@ -23,11 +23,11 @@ from mock import MagicMock
from watcher.common import exception from watcher.common import exception
from watcher.decision_engine.meta_action.hypervisor_state import \ from watcher.decision_engine.actions.hypervisor_state import \
ChangeHypervisorState ChangeHypervisorState
from watcher.decision_engine.meta_action.power_state import ChangePowerState from watcher.decision_engine.actions.power_state import ChangePowerState
from watcher.decision_engine.meta_action.migrate import Migrate from watcher.decision_engine.actions.migration import Migrate
from watcher.decision_engine.model.model_root import ModelRoot from watcher.decision_engine.model.model_root import ModelRoot
from watcher.decision_engine.strategy.basic_consolidation import \ from watcher.decision_engine.strategy.basic_consolidation import \
BasicConsolidation BasicConsolidation
@@ -151,24 +151,6 @@ class TestBasicConsolidation(base.BaseTestCase):
self.assertRaises(exception.ClusteStateNotDefined, self.assertRaises(exception.ClusteStateNotDefined,
sercon.print_utilization, None) sercon.print_utilization, None)
def check_migration(self, array, indice, vm, src, dest):
"""Helper to check migration
:param array:
:param indice:
:param vm:
:param src:
:param dest:
:return:
"""
self.assertEqual(array[indice].get_vm().uuid, vm)
self.assertEqual(array[indice].get_source_hypervisor().uuid, src)
self.assertEqual(array[indice].get_dest_hypervisor().uuid, dest)
self.assertEqual(array[indice].get_bandwidth(), 0)
array[indice].set_bandwidth(5)
self.assertEqual(array[indice].get_bandwidth(), 5)
def test_check_migration(self): def test_check_migration(self):
sercon = BasicConsolidation() sercon = BasicConsolidation()
fake_cluster = FakerModelCollector() fake_cluster = FakerModelCollector()
@@ -209,7 +191,7 @@ class TestBasicConsolidation(base.BaseTestCase):
self.fake_cluster.generate_scenario_3()) self.fake_cluster.generate_scenario_3())
actions_counter = Counter( actions_counter = Counter(
[type(action) for action in solution.meta_actions]) [type(action) for action in solution.actions])
expected_num_migrations = 0 expected_num_migrations = 0
expected_power_state = 0 expected_power_state = 0

View File

@@ -19,7 +19,7 @@ from mock import MagicMock
from watcher.common.exception import MetaActionNotFound from watcher.common.exception import MetaActionNotFound
from watcher.common import utils from watcher.common import utils
from watcher.db import api as db_api from watcher.db import api as db_api
from watcher.decision_engine.meta_action.base import MetaAction from watcher.decision_engine.actions.base import BaseAction
from watcher.decision_engine.planner.default import DefaultPlanner from watcher.decision_engine.planner.default import DefaultPlanner
from watcher.decision_engine.solution.default import DefaultSolution from watcher.decision_engine.solution.default import DefaultSolution
from watcher.decision_engine.strategy.basic_consolidation import \ from watcher.decision_engine.strategy.basic_consolidation import \
@@ -62,7 +62,7 @@ class TestActionScheduling(base.DbTestCase):
scenarios = [ scenarios = [
(str(action_cls), {"fake_action": mock.Mock(spec=action_cls)}) (str(action_cls), {"fake_action": mock.Mock(spec=action_cls)})
for action_cls in MetaAction.__subclasses__() for action_cls in BaseAction.__subclasses__()
] ]
def test_schedule_actions(self): def test_schedule_actions(self):
@@ -119,7 +119,7 @@ class TestDefaultPlanner(base.DbTestCase):
def test_schedule_raise(self): def test_schedule_raise(self):
audit = db_utils.create_test_audit(uuid=utils.generate_uuid()) audit = db_utils.create_test_audit(uuid=utils.generate_uuid())
fake_solution = SolutionFaker.build() fake_solution = SolutionFaker.build()
fake_solution._meta_actions[0] = "valeur_qcq" fake_solution.actions[0] = "valeur_qcq"
self.assertRaises(MetaActionNotFound, self.default_planner.schedule, self.assertRaises(MetaActionNotFound, self.default_planner.schedule,
self.context, audit.id, fake_solution) self.context, audit.id, fake_solution)

View File

@@ -21,4 +21,4 @@ class TestDefaultSolution(base.BaseTestCase):
def test_default_solution(self): def test_default_solution(self):
solution = DefaultSolution() solution = DefaultSolution()
solution.add_change_request("BLA") solution.add_change_request("BLA")
self.assertEqual(solution.meta_actions[0], "BLA") self.assertEqual(solution.actions[0], "BLA")