Merge "Watcher Planner Selector"

This commit is contained in:
Zuul 2018-05-23 08:28:46 +00:00 committed by Gerrit Code Review
commit 9f129ffb1c

View File

@ -0,0 +1,218 @@
..
This work is licensed under a Creative Commons Attribution 3.0 Unported
License.
http://creativecommons.org/licenses/by/3.0/legalcode
========================
Watcher Planner Selector
========================
https://blueprints.launchpad.net/watcher/+spec/watcher-planner-selector
`Watcher Planner`_ takes the set of `Actions`_ generated by a `Strategy`_ and
builds the design of a workflow which defines how-to schedule in time those
different Actions and for each Action what are the prerequisite conditions.
It is only possible to choose only one (default) `Planner`_ for all strategies
now.
Custom Planners could be added to Watcher, thereby users can adapt Watcher
workflow to their needs. As one of the ways for customization, the option
could be added to set concrete Planner for specific Strategy that takes
features of users' workflow into account.
Problem description
===================
Currently there is no opportunity to set unique Planner to specific Strategy.
User can set default Planner in config file that would be used alongside every
Audit.
If using different Planner is the case, user should change default
value to desired one. By doing this we restrict ourselves to use this new
Planner with all of the Strategies, what is not desired because some of
`Solutions`_ generated by Strategies could be not compatible with the schedule
made by this Planner.
Use Cases
----------
* As an Strategy developer, I want to choose what Planner would be applied to the
Solution generated by my Strategy.
* As an Strategy developer, I expect that if I provide no Planner to my Strategy, it
will use default Planner that is set in base Strategy..
Proposed change
===============
We propose to add property to base Strategy class, say 'planner', and set
default value to this option in concrete Strategies where appropriate (for
example, 'workload_stabilization' Planner as default for Strategy with the
same name).
Planner should be load in AuditHandler. Currently it's done with the help of
PlannerManager, that loads sole planner for every Strategy which set by
CONF.watcher_planner.planner value. Definitely, PlannerManager do only
loading job, so it's better to load Planner without this intermediate layer.
Thus we propose to exchange AuditHandler._planner_manager with
DefaultPlannerLoader. As a result, PlannerManager could be removed from
Watcher.
Therefore, AuditHandler now should pass desired Planner name to Loader.
We propose to get this name from property of the Strategy used in current
Audit. In this case we ought to get Strategy object associated with current
Audit.
For this propose, we need to be able to get Strategy prior to
AuditHandler._planner_loader.load() method call. It could be be done with the
help of StrategyContext class that loads Strategy based on names of Goal and
Audit. The problem is that this loading is done during do_execute_strategy()
what's a bad design. We propose to move *selecting* of strategy to distinct
method, say 'select_strategy':
::
def select_strategy(audit, request_context):
osc = clients.OpenStackClients()
goal = objects.Goal.get_by_id(request_context, audit.goal_id)
strategy_name = None
if audit.strategy_id:
strategy = objects.Strategy.get_by_id(
request_context, audit.strategy_id)
strategy_name = strategy.name
strategy_selector = default.DefaultStrategySelector(
goal_name=goal.name,
strategy_name=strategy_name,
osc=osc)
return strategy_selector.select()
Now we could call this method not only in do_execute_strategy() to pick
strategy only for execution, but also call it in AuditHandler.
Another benefit to do it in this manner is that if Audit was created without
specified Strategy, StrategyContext will take care to retrieve default
Strategy for this Goal.
By design, whole AuditHandler class passes current Audit as an argument of
many of its methods. It would be convenient to have current Audit as a field of
AuditHandler class. Also, it is good design decision, because it's true OOP
paradigm. To sum up, we propose to remove all these arguments and replace
them with class field.
As a result, we can get Planner for current Strategy without adding new
argument to AuditHandler.planner() or storing name of Strategy in additional
field.
Alternatives
------------
Alternatively, we could pass Planner name as argument during creation of
AuditTemplate.
As an alternative to changing signatures of AuditHandler methods we could add a
new field only for Strategy name.
Data model impact
-----------------
None
REST API impact
---------------
None
Security impact
---------------
None
Notifications impact
--------------------
None
Other end user impact
---------------------
None
Performance Impact
------------------
None
Other deployer impact
---------------------
None
Developer impact
----------------
Signature of PlannerManager.load() method changes.
AuditHandler methods change their signatures, 'audit' argument would be
replaced with same class field.
Implementation
==============
Assignee(s)
-----------
Primary assignee:
Egor Panfilov <erakli>
Work Items
----------
* Refactor DefaultStrategyContext.do_execute_strategy() and add
select_strategy() method
* Add 'planner' property to BaseStrategy
* Replace PlannerManager with PlannerLoader in AuditHandler
* Rewrite AuditHandler methods so that 'audit' argument would be replaced
with class' field
Dependencies
============
https://blueprints.launchpad.net/watcher/+spec/planner-storage-action-plan
Testing
=======
Tests with different Planners assigned to different Strategies should be
implemented.
Documentation Impact
====================
Documentation should be updated to explain how to set 'planner' option.
References
==========
None
History
=======
None
.. _Actions: https://docs.openstack.org/watcher/latest/glossary.html#action
.. _Strategy: https://docs.openstack.org/watcher/latest/glossary.html#strategy
.. _Solutions: https://docs.openstack.org/watcher/latest/glossary.html#solution
.. _Planner: https://docs.openstack.org/watcher/latest/glossary.html#watcher-planner
.. _Watcher Planner: https://docs.openstack.org/watcher/latest/glossary.html#watcher-planner