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):
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 ...
return self.solution

View File

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

View File

@@ -16,18 +16,17 @@
# See the License for the specific language governing permissions and
# 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
class ChangeHypervisorState(MetaAction):
class ChangeHypervisorState(BaseAction):
def __init__(self, target):
MetaAction.__init__(self)
'''The target host to change the power
'''The target host to change the state
:param target:
:return:
:param target: the target hypervisor uuid
'''
super(ChangeHypervisorState, self).__init__()
self._target = target
self._state = HypervisorState.ONLINE
@@ -48,5 +47,5 @@ class ChangeHypervisorState(MetaAction):
self._target = p
def __str__(self):
return "{0} {1} ChangeHypervisorState => {2}".format(
MetaAction.__str__(self), self.target, self.state)
return "{} ChangeHypervisorState => {}".format(self.target,
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.
#
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):
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
# 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
class ChangePowerState(MetaAction):
class ChangePowerState(BaseAction):
def __init__(self, target):
MetaAction.__init__(self)
"""The target host to change the power
:param target:
:return:
"""
super(ChangePowerState, self).__init__()
self._target = target
self._power_state = PowerState.g0
@@ -44,10 +43,9 @@ class ChangePowerState(MetaAction):
return self._target
@target.setter
def target(self, p):
self._target = p
def target(self, t):
self._target = t
def __str__(self):
return "{0} ChangePowerState {1} => {2} ".format(
MetaAction.__str__(self),
return "ChangePowerState {} => {} ".format(
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.decision_engine.meta_action.hypervisor_state import \
from watcher.decision_engine.actions.hypervisor_state import \
ChangeHypervisorState
from watcher.decision_engine.meta_action.migrate import Migrate
from watcher.decision_engine.meta_action.nop import Nop
from watcher.decision_engine.meta_action.power_state import ChangePowerState
from watcher.decision_engine.actions.migration import Migrate
from watcher.decision_engine.actions.nop import Nop
from watcher.decision_engine.actions.power_state import ChangePowerState
from watcher.objects.action import Status as AStatus
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')
action_plan = self._create_action_plan(context, audit_id)
actions = list(solution.meta_actions)
actions = list(solution.actions)
to_schedule = []
for action in actions:
@@ -92,10 +92,10 @@ class DefaultPlanner(Planner):
# TODO(jed) type
primitive = self.create_action(action_plan.id,
Primitives.LIVE_MIGRATE.value,
action.get_vm().uuid,
action.get_source_hypervisor().
action.vm.uuid,
action.src_hypervisor.
uuid,
action.get_dest_hypervisor().
action.dest_hypervisor.
uuid,
description="{0}".format(
action)

View File

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

View File

@@ -24,20 +24,21 @@ LOG = log.getLogger(__name__)
class DefaultSolution(Solution):
def __init__(self):
self._meta_actions = []
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
"""The DefaultSolution class store a set of actions generated by a
strategy in order to achieve the goal.
"""
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.
#
from oslo_log import log
from watcher.common.exception import ClusterEmpty
from watcher.common.exception import ClusteStateNotDefined
from watcher.decision_engine.strategy.base import BaseStrategy
from watcher.decision_engine.strategy.level import StrategyLevel
from watcher.decision_engine.meta_action.hypervisor_state import \
from watcher.decision_engine.actions.hypervisor_state import \
ChangeHypervisorState
from watcher.decision_engine.meta_action.migrate import Migrate
from watcher.decision_engine.meta_action.migrate import MigrationType
from watcher.decision_engine.meta_action.power_state import ChangePowerState
from watcher.decision_engine.meta_action.power_state import PowerState
from watcher.decision_engine.actions.migration import Migrate
from watcher.decision_engine.actions.migration import MigrationType
from watcher.decision_engine.actions.power_state import ChangePowerState
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.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 \
CeilometerClusterHistory
@@ -39,7 +37,6 @@ LOG = log.getLogger(__name__)
class BasicConsolidation(BaseStrategy):
DEFAULT_NAME = "basic"
DEFAULT_DESCRIPTION = "Basic offline consolidation"
@@ -447,8 +444,8 @@ class BasicConsolidation(BaseStrategy):
mig_src_hypervisor,
mig_dst_hypervisor)
# live migration
live_migrate.set_migration_type(
MigrationType.pre_copy)
live_migrate.migration_type = \
MigrationType.pre_copy
live_migrate.level = StrategyLevel.conservative
tmp_vm_migration_schedule.append(live_migrate)

View File

@@ -18,7 +18,7 @@
#
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
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
# 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
class TestMetaAction(base.TestCase):
class TestAction(base.TestCase):
def test_get_priority(self):
ma = MetaAction()
ma = BaseAction()
ma.priority = 3
self.assertEqual(ma.priority, 3)
def test_get_level(self):
ma = MetaAction()
ma = BaseAction()
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.decision_engine.meta_action.hypervisor_state import \
from watcher.decision_engine.actions.hypervisor_state import \
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.strategy.basic_consolidation import \
BasicConsolidation
@@ -151,24 +151,6 @@ class TestBasicConsolidation(base.BaseTestCase):
self.assertRaises(exception.ClusteStateNotDefined,
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):
sercon = BasicConsolidation()
fake_cluster = FakerModelCollector()
@@ -209,7 +191,7 @@ class TestBasicConsolidation(base.BaseTestCase):
self.fake_cluster.generate_scenario_3())
actions_counter = Counter(
[type(action) for action in solution.meta_actions])
[type(action) for action in solution.actions])
expected_num_migrations = 0
expected_power_state = 0

View File

@@ -19,7 +19,7 @@ from mock import MagicMock
from watcher.common.exception import MetaActionNotFound
from watcher.common import utils
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.solution.default import DefaultSolution
from watcher.decision_engine.strategy.basic_consolidation import \
@@ -62,8 +62,8 @@ class TestActionScheduling(base.DbTestCase):
scenarios = [
(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):
default_planner = DefaultPlanner()
@@ -119,7 +119,7 @@ class TestDefaultPlanner(base.DbTestCase):
def test_schedule_raise(self):
audit = db_utils.create_test_audit(uuid=utils.generate_uuid())
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.context, audit.id, fake_solution)

View File

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