Updated Strategy plugin doc
As we modified the way a strategy gets implemented in blueprint watcher-add-actions-via-conf, this patchset updates the documentation regarding the implementation of a strategy plugin. Change-Id: I517455bc34623feff704956ce30ed545a0e1014b Closes-Bug: #1533740
This commit is contained in:
committed by
David TARDIVEL
parent
9fadfbe40a
commit
4afefa3dfb
@@ -12,11 +12,11 @@ Build a new optimization strategy
|
|||||||
|
|
||||||
Watcher Decision Engine has an external :ref:`strategy <strategy_definition>`
|
Watcher Decision Engine has an external :ref:`strategy <strategy_definition>`
|
||||||
plugin interface which gives anyone the ability to integrate an external
|
plugin interface which gives anyone the ability to integrate an external
|
||||||
:ref:`strategy <strategy_definition>` in order to make use of placement
|
strategy in order to make use of placement algorithms.
|
||||||
algorithms.
|
|
||||||
|
|
||||||
This section gives some guidelines on how to implement and integrate custom
|
This section gives some guidelines on how to implement and integrate custom
|
||||||
Stategies with Watcher.
|
strategies with Watcher.
|
||||||
|
|
||||||
|
|
||||||
Pre-requisites
|
Pre-requisites
|
||||||
==============
|
==============
|
||||||
@@ -31,15 +31,16 @@ Creating a new plugin
|
|||||||
|
|
||||||
First of all you have to:
|
First of all you have to:
|
||||||
|
|
||||||
- Extend the base ``BaseStrategy`` class
|
- Extend :py:class:`~.BaseStrategy`
|
||||||
- Implement its ``execute`` method
|
- Implement its :py:meth:`~.BaseStrategy.execute` method
|
||||||
|
|
||||||
Here is an example showing how you can write a plugin called ``DummyStrategy``:
|
Here is an example showing how you can write a plugin called ``DummyStrategy``:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
# Filepath = third-party/third_party/dummy.py
|
# Filepath = third-party/thirdparty/dummy.py
|
||||||
# Import path = third_party.dummy
|
# Import path = thirdparty.dummy
|
||||||
|
import uuid
|
||||||
|
|
||||||
class DummyStrategy(BaseStrategy):
|
class DummyStrategy(BaseStrategy):
|
||||||
|
|
||||||
@@ -50,14 +51,25 @@ Here is an example showing how you can write a plugin called ``DummyStrategy``:
|
|||||||
super(DummyStrategy, self).__init__(name, description)
|
super(DummyStrategy, self).__init__(name, description)
|
||||||
|
|
||||||
def execute(self, model):
|
def execute(self, model):
|
||||||
self.solution.add_change_request(
|
migration_type = 'live'
|
||||||
Migrate(vm=my_vm, src_hypervisor=src, dest_hypervisor=dest)
|
src_hypervisor = 'compute-host-1'
|
||||||
)
|
dst_hypervisor = 'compute-host-2'
|
||||||
|
instance_id = uuid.uuid4()
|
||||||
|
parameters = {'migration_type': migration_type,
|
||||||
|
'src_hypervisor': src_hypervisor,
|
||||||
|
'dst_hypervisor': dst_hypervisor}
|
||||||
|
self.solution.add_action(action_type="migration",
|
||||||
|
resource_id=instance_id,
|
||||||
|
input_parameters=parameters)
|
||||||
# Do some more stuff here ...
|
# Do some more stuff here ...
|
||||||
return self.solution
|
return self.solution
|
||||||
|
|
||||||
As you can see in the above example, the ``execute()`` method returns a
|
As you can see in the above example, the :py:meth:`~.BaseStrategy.execute`
|
||||||
solution as required.
|
method returns a :py:class:`~.BaseSolution` instance as required. This solution
|
||||||
|
is what wraps the abstract set of actions the strategy recommends to you. This
|
||||||
|
solution is then processed by a :ref:`planner <planner_definition>` to produce
|
||||||
|
an action plan which shall contain the sequenced flow of actions to be
|
||||||
|
executed by the :ref:`Watcher Applier <watcher_applier_definition>`.
|
||||||
|
|
||||||
Please note that your strategy class will be instantiated without any
|
Please note that your strategy class will be instantiated without any
|
||||||
parameter. Therefore, you should make sure not to make any of them required in
|
parameter. Therefore, you should make sure not to make any of them required in
|
||||||
@@ -67,13 +79,10 @@ your ``__init__`` method.
|
|||||||
Abstract Plugin Class
|
Abstract Plugin Class
|
||||||
=====================
|
=====================
|
||||||
|
|
||||||
Here below is the abstract ``BaseStrategy`` class that every single strategy
|
Here below is the abstract :py:class:`~.BaseStrategy` class that every single
|
||||||
should implement:
|
strategy should implement:
|
||||||
|
|
||||||
.. automodule:: watcher.decision_engine.strategy.strategies.base
|
.. autoclass:: watcher.decision_engine.strategy.strategies.base.BaseStrategy
|
||||||
:noindex:
|
|
||||||
|
|
||||||
.. autoclass:: BaseStrategy
|
|
||||||
:members:
|
:members:
|
||||||
:noindex:
|
:noindex:
|
||||||
|
|
||||||
@@ -94,11 +103,11 @@ Here below is how you would proceed to register ``DummyStrategy`` using pbr_:
|
|||||||
|
|
||||||
[entry_points]
|
[entry_points]
|
||||||
watcher_strategies =
|
watcher_strategies =
|
||||||
dummy = third_party.dummy:DummyStrategy
|
dummy = thirdparty.dummy:DummyStrategy
|
||||||
|
|
||||||
|
|
||||||
To get a better understanding on how to implement a more advanced strategy,
|
To get a better understanding on how to implement a more advanced strategy,
|
||||||
have a look at the :py:class:`BasicConsolidation` class.
|
have a look at the :py:class:`~.BasicConsolidation` class.
|
||||||
|
|
||||||
.. _pbr: http://docs.openstack.org/developer/pbr/
|
.. _pbr: http://docs.openstack.org/developer/pbr/
|
||||||
|
|
||||||
@@ -106,12 +115,12 @@ Using strategy plugins
|
|||||||
======================
|
======================
|
||||||
|
|
||||||
The Watcher Decision Engine service will automatically discover any installed
|
The Watcher Decision Engine service will automatically discover any installed
|
||||||
plugins when it is run. If a Python package containing a custom plugin is
|
plugins when it is restarted. If a Python package containing a custom plugin is
|
||||||
installed within the same environment as Watcher, Watcher will automatically
|
installed within the same environment as Watcher, Watcher will automatically
|
||||||
make that plugin available for use.
|
make that plugin available for use.
|
||||||
|
|
||||||
At this point, the way Watcher will use your new strategy if you reference it
|
At this point, Watcher will use your new strategy if you reference it in the
|
||||||
in the ``goals`` under the ``[watcher_goals]`` section of your ``watcher.conf``
|
``goals`` under the ``[watcher_goals]`` section of your ``watcher.conf``
|
||||||
configuration file. For example, if you want to use a ``dummy`` strategy you
|
configuration file. For example, if you want to use a ``dummy`` strategy you
|
||||||
just installed, you would have to associate it to a goal like this:
|
just installed, you would have to associate it to a goal like this:
|
||||||
|
|
||||||
@@ -145,13 +154,13 @@ pluggable backend.
|
|||||||
Finally, if your strategy requires new metrics not covered by Ceilometer, you
|
Finally, if your strategy requires new metrics not covered by Ceilometer, you
|
||||||
can add them through a Ceilometer `plugin`_.
|
can add them through a Ceilometer `plugin`_.
|
||||||
|
|
||||||
|
|
||||||
.. _`Helper`: https://github.com/openstack/watcher/blob/master/watcher/metrics_engine/cluster_history/ceilometer.py#L31
|
.. _`Helper`: https://github.com/openstack/watcher/blob/master/watcher/metrics_engine/cluster_history/ceilometer.py#L31
|
||||||
.. _`Ceilometer developer guide`: http://docs.openstack.org/developer/ceilometer/architecture.html#storing-the-data
|
.. _`Ceilometer developer guide`: http://docs.openstack.org/developer/ceilometer/architecture.html#storing-the-data
|
||||||
.. _`here`: http://docs.openstack.org/developer/ceilometer/install/dbreco.html#choosing-a-database-backend
|
.. _`here`: http://docs.openstack.org/developer/ceilometer/install/dbreco.html#choosing-a-database-backend
|
||||||
.. _`plugin`: http://docs.openstack.org/developer/ceilometer/plugins.html
|
.. _`plugin`: http://docs.openstack.org/developer/ceilometer/plugins.html
|
||||||
.. _`Ceilosca`: https://github.com/openstack/monasca-ceilometer/blob/master/ceilosca/ceilometer/storage/impl_monasca.py
|
.. _`Ceilosca`: https://github.com/openstack/monasca-ceilometer/blob/master/ceilosca/ceilometer/storage/impl_monasca.py
|
||||||
|
|
||||||
|
|
||||||
Read usage metrics using the Python binding
|
Read usage metrics using the Python binding
|
||||||
-------------------------------------------
|
-------------------------------------------
|
||||||
|
|
||||||
@@ -159,39 +168,43 @@ You can find the information about the Ceilometer Python binding on the
|
|||||||
OpenStack `ceilometer client python API documentation
|
OpenStack `ceilometer client python API documentation
|
||||||
<http://docs.openstack.org/developer/python-ceilometerclient/api.html>`_
|
<http://docs.openstack.org/developer/python-ceilometerclient/api.html>`_
|
||||||
|
|
||||||
The first step is to authenticate against the Ceilometer service
|
To facilitate the process, Watcher provides the ``osc`` attribute to every
|
||||||
(assuming that you already imported the Ceilometer client for Python)
|
strategy which includes clients to major OpenStack services, including
|
||||||
with this call:
|
Ceilometer. So to access it within your strategy, you can do the following:
|
||||||
|
|
||||||
.. code-block:: py
|
.. code-block:: py
|
||||||
|
|
||||||
cclient = ceilometerclient.client.get_client(VERSION, os_username=USERNAME,
|
# Within your strategy "execute()"
|
||||||
os_password=PASSWORD, os_tenant_name=PROJECT_NAME, os_auth_url=AUTH_URL)
|
cclient = self.osc.ceilometer
|
||||||
|
# TODO: Do something here
|
||||||
|
|
||||||
Using that you can now query the values for that specific metric:
|
Using that you can now query the values for that specific metric:
|
||||||
|
|
||||||
.. code-block:: py
|
.. code-block:: py
|
||||||
|
|
||||||
value_cpu = cclient.samples.list(meter_name='cpu_util', limit=10, q=query)
|
query = None # e.g. [{'field': 'foo', 'op': 'le', 'value': 34},]
|
||||||
|
value_cpu = cclient.samples.list(
|
||||||
|
meter_name='cpu_util',
|
||||||
|
limit=10, q=query)
|
||||||
|
|
||||||
|
|
||||||
Read usage metrics using the Watcher Cluster History Helper
|
Read usage metrics using the Watcher Cluster History Helper
|
||||||
-----------------------------------------------------------
|
-----------------------------------------------------------
|
||||||
|
|
||||||
Here below is the abstract ``BaseClusterHistory`` class of the Helper.
|
Here below is the abstract ``BaseClusterHistory`` class of the Helper.
|
||||||
|
|
||||||
.. automodule:: watcher.metrics_engine.cluster_history.api
|
.. autoclass:: watcher.metrics_engine.cluster_history.api.BaseClusterHistory
|
||||||
:noindex:
|
|
||||||
|
|
||||||
.. autoclass:: BaseClusterHistory
|
|
||||||
:members:
|
:members:
|
||||||
:noindex:
|
:noindex:
|
||||||
|
|
||||||
|
|
||||||
The following snippet code shows how to create a Cluster History class:
|
The following code snippet shows how to create a Cluster History class:
|
||||||
|
|
||||||
.. code-block:: py
|
.. code-block:: py
|
||||||
|
|
||||||
query_history = CeilometerClusterHistory()
|
from watcher.metrics_engine.cluster_history import ceilometer as ceil
|
||||||
|
|
||||||
|
query_history = ceil.CeilometerClusterHistory()
|
||||||
|
|
||||||
Using that you can now query the values for that specific metric:
|
Using that you can now query the values for that specific metric:
|
||||||
|
|
||||||
@@ -202,4 +215,3 @@ Using that you can now query the values for that specific metric:
|
|||||||
period="7200",
|
period="7200",
|
||||||
aggregate='avg'
|
aggregate='avg'
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -72,10 +72,10 @@ Plugins
|
|||||||
.. toctree::
|
.. toctree::
|
||||||
:maxdepth: 1
|
:maxdepth: 1
|
||||||
|
|
||||||
dev/strategy-plugin
|
dev/plugin/strategy-plugin
|
||||||
dev/planner-plugin
|
|
||||||
dev/plugins
|
|
||||||
dev/plugin/action-plugin
|
dev/plugin/action-plugin
|
||||||
|
dev/plugin/planner-plugin
|
||||||
|
dev/plugins
|
||||||
|
|
||||||
|
|
||||||
Admin Guide
|
Admin Guide
|
||||||
|
|||||||
@@ -63,7 +63,8 @@ watcher_planners =
|
|||||||
default = watcher.decision_engine.planner.default:DefaultPlanner
|
default = watcher.decision_engine.planner.default:DefaultPlanner
|
||||||
|
|
||||||
[pbr]
|
[pbr]
|
||||||
autodoc_index_modules = True
|
warnerrors = true
|
||||||
|
autodoc_index_modules = true
|
||||||
autodoc_exclude_modules =
|
autodoc_exclude_modules =
|
||||||
watcher.db.sqlalchemy.alembic.env
|
watcher.db.sqlalchemy.alembic.env
|
||||||
watcher.db.sqlalchemy.alembic.versions.*
|
watcher.db.sqlalchemy.alembic.versions.*
|
||||||
|
|||||||
Reference in New Issue
Block a user