Provide a more dynamic Actions management solution
Today, the set of possible `Actions`_ is fixed for a given version of Watcher and enables optimization algorithms to include actions such as instance migration, changing hypervisor state, changing power state (ACPI level, ...). It should be possible to deploy and configure (in watcher.conf) new potential `Actions`_ and associate each `Action`_ to a Python class, without the need to redeploy a new version of Watcher. Change-Id: If4b68079967854f9040f11206e2b6202a66d8551 blueprint: watcher-add-actions-via-conf
This commit is contained in:
parent
386c3a2a88
commit
ad63b7d0af
Binary file not shown.
BIN
doc/source/images/Watcher_Actions_Management_Functional_Need.png
Normal file
BIN
doc/source/images/Watcher_Actions_Management_Functional_Need.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 26 KiB |
171
doc/source/images/Watcher_Actions_Management_Functional_Need.svg
Normal file
171
doc/source/images/Watcher_Actions_Management_Functional_Need.svg
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/PR-SVG-20010719/DTD/svg10.dtd">
|
||||||
|
<svg width="63cm" height="20cm" viewBox="44 44 1245 385" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<g>
|
||||||
|
<rect style="fill: #fad21b" x="46" y="46" width="1242" height="382"/>
|
||||||
|
<rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="46" y="46" width="1242" height="382"/>
|
||||||
|
<text font-size="12.8" style="fill: #000000;text-anchor:middle;font-family:sans-serif;font-style:normal;font-weight:normal" x="667" y="240.9">
|
||||||
|
<tspan x="667" y="240.9"></tspan>
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<text font-size="15.4545" style="fill: #000000;text-anchor:start;font-family:sans-serif;font-style:normal;font-weight:700" x="63.6" y="73.45">
|
||||||
|
<tspan x="63.6" y="73.45">Functional Need</tspan>
|
||||||
|
</text>
|
||||||
|
<g>
|
||||||
|
<polygon style="fill: #ffc0cb" points="209,220 338.2,220 350.2,232 350.2,254 209,254 "/>
|
||||||
|
<polygon style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" points="209,220 338.2,220 350.2,232 350.2,254 209,254 "/>
|
||||||
|
<polyline style="fill: none; fill-opacity:0; stroke-width: 1; stroke: #000000" points="338.2,220 338.2,232 350.2,232 "/>
|
||||||
|
<text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="216" y="244.9">
|
||||||
|
<tspan x="216" y="244.9">Watcher Strategy</tspan>
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<polygon style="fill: #ffc0cb" points="550.6,220.1 672.1,220.1 684.1,232.1 684.1,254.1 550.6,254.1 "/>
|
||||||
|
<polygon style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" points="550.6,220.1 672.1,220.1 684.1,232.1 684.1,254.1 550.6,254.1 "/>
|
||||||
|
<polyline style="fill: none; fill-opacity:0; stroke-width: 1; stroke: #000000" points="672.1,220.1 672.1,232.1 684.1,232.1 "/>
|
||||||
|
<text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="557.6" y="245">
|
||||||
|
<tspan x="557.6" y="245">Watcher Planner</tspan>
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<polygon style="fill: #ffc0cb" points="896.6,212.1 1018.1,212.1 1030.1,224.1 1030.1,246.1 896.6,246.1 "/>
|
||||||
|
<polygon style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" points="896.6,212.1 1018.1,212.1 1030.1,224.1 1030.1,246.1 896.6,246.1 "/>
|
||||||
|
<polyline style="fill: none; fill-opacity:0; stroke-width: 1; stroke: #000000" points="1018.1,212.1 1018.1,224.1 1030.1,224.1 "/>
|
||||||
|
<text font-size="12.8" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="903.6" y="237">
|
||||||
|
<tspan x="903.6" y="237">Watcher Applier</tspan>
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<rect style="fill: #ffb400" x="158" y="254" width="241.25" height="52" rx="20" ry="20"/>
|
||||||
|
<rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="158" y="254" width="241.25" height="52" rx="20" ry="20"/>
|
||||||
|
<text font-size="12.8" style="fill: #000000;text-anchor:middle;font-family:sans-serif;font-style:normal;font-weight:700" x="278.625" y="275.9">
|
||||||
|
<tspan x="278.625" y="275.9">Define and instanciate Actions</tspan>
|
||||||
|
<tspan x="278.625" y="291.9">for Optimization</tspan>
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<rect style="fill: #ffb400" x="545" y="254" width="143.9" height="52" rx="20" ry="20"/>
|
||||||
|
<rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="545" y="254" width="143.9" height="52" rx="20" ry="20"/>
|
||||||
|
<text font-size="12.8" style="fill: #000000;text-anchor:middle;font-family:sans-serif;font-style:normal;font-weight:700" x="616.95" y="275.9">
|
||||||
|
<tspan x="616.95" y="275.9">Schedule Actions</tspan>
|
||||||
|
<tspan x="616.95" y="291.9">in Time</tspan>
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<rect style="fill: #ffb400" x="898" y="246" width="135.15" height="68" rx="20" ry="20"/>
|
||||||
|
<rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="898" y="246" width="135.15" height="68" rx="20" ry="20"/>
|
||||||
|
<text font-size="12.8" style="fill: #000000;text-anchor:middle;font-family:sans-serif;font-style:normal;font-weight:700" x="965.575" y="267.9">
|
||||||
|
<tspan x="965.575" y="267.9">Simulate</tspan>
|
||||||
|
<tspan x="965.575" y="283.9">and</tspan>
|
||||||
|
<tspan x="965.575" y="299.9">Execute Actions</tspan>
|
||||||
|
</text>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<polyline style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" points="399.25,280 409.25,280 535,280 540.528,280 "/>
|
||||||
|
<polyline style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" points="532.764,285 542.764,280 532.764,275 "/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<polyline style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" points="688.9,280 698.9,280 888,280 893.528,280 "/>
|
||||||
|
<polyline style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" points="885.764,285 895.764,280 885.764,275 "/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<rect style="fill: #ffffff" x="407" y="293.1" width="131.2" height="100"/>
|
||||||
|
<rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="407" y="293.1" width="131.2" height="100"/>
|
||||||
|
<text font-size="12.8" style="fill: #000000;text-anchor:middle;font-family:sans-serif;font-style:normal;font-weight:normal" x="472.6" y="315">
|
||||||
|
<tspan x="472.6" y="315">List of Actions</tspan>
|
||||||
|
<tspan x="472.6" y="331">+</tspan>
|
||||||
|
<tspan x="472.6" y="347">input parameters</tspan>
|
||||||
|
<tspan x="472.6" y="363">+</tspan>
|
||||||
|
<tspan x="472.6" y="379">target resource</tspan>
|
||||||
|
</text>
|
||||||
|
<line style="fill: none; fill-opacity:0; stroke-width: 1; stroke: #000000" x1="427.725" y1="318" x2="517.475" y2="318"/>
|
||||||
|
<line style="fill: none; fill-opacity:0; stroke-width: 1; stroke: #000000" x1="467.225" y1="334" x2="477.975" y2="334"/>
|
||||||
|
<line style="fill: none; fill-opacity:0; stroke-width: 1; stroke: #000000" x1="417" y1="350" x2="528.2" y2="350"/>
|
||||||
|
<line style="fill: none; fill-opacity:0; stroke-width: 1; stroke: #000000" x1="467.225" y1="366" x2="477.975" y2="366"/>
|
||||||
|
<line style="fill: none; fill-opacity:0; stroke-width: 1; stroke: #000000" x1="423.025" y1="382" x2="522.175" y2="382"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<rect style="fill: #ffffff" x="708.6" y="293.1" width="172.6" height="36"/>
|
||||||
|
<rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="708.6" y="293.1" width="172.6" height="36"/>
|
||||||
|
<text font-size="12.8" style="fill: #000000;text-anchor:middle;font-family:sans-serif;font-style:normal;font-weight:normal" x="794.9" y="315">
|
||||||
|
<tspan x="794.9" y="315">Actions flow description</tspan>
|
||||||
|
</text>
|
||||||
|
<line style="fill: none; fill-opacity:0; stroke-width: 1; stroke: #000000" x1="718.6" y1="318" x2="871.2" y2="318"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<rect style="fill: #ffffff" x="1047.6" y="293.1" width="111.6" height="100"/>
|
||||||
|
<rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="1047.6" y="293.1" width="111.6" height="100"/>
|
||||||
|
<text font-size="12.8" style="fill: #000000;text-anchor:middle;font-family:sans-serif;font-style:normal;font-weight:normal" x="1103.4" y="315">
|
||||||
|
<tspan x="1103.4" y="315">History</tspan>
|
||||||
|
<tspan x="1103.4" y="331">+</tspan>
|
||||||
|
<tspan x="1103.4" y="347">Output results</tspan>
|
||||||
|
<tspan x="1103.4" y="363">+</tspan>
|
||||||
|
<tspan x="1103.4" y="379">Events</tspan>
|
||||||
|
</text>
|
||||||
|
<line style="fill: none; fill-opacity:0; stroke-width: 1; stroke: #000000" x1="1080.63" y1="318" x2="1126.18" y2="318"/>
|
||||||
|
<line style="fill: none; fill-opacity:0; stroke-width: 1; stroke: #000000" x1="1098.03" y1="334" x2="1108.78" y2="334"/>
|
||||||
|
<line style="fill: none; fill-opacity:0; stroke-width: 1; stroke: #000000" x1="1057.6" y1="350" x2="1149.2" y2="350"/>
|
||||||
|
<line style="fill: none; fill-opacity:0; stroke-width: 1; stroke: #000000" x1="1098.03" y1="366" x2="1108.78" y2="366"/>
|
||||||
|
<line style="fill: none; fill-opacity:0; stroke-width: 1; stroke: #000000" x1="1081.72" y1="382" x2="1125.07" y2="382"/>
|
||||||
|
</g>
|
||||||
|
<ellipse style="fill: #000000" cx="99" cy="280" rx="10" ry="10"/>
|
||||||
|
<g>
|
||||||
|
<ellipse style="fill: #ffffff" cx="1212" cy="280" rx="15" ry="15"/>
|
||||||
|
<ellipse style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" cx="1212" cy="280" rx="15" ry="15"/>
|
||||||
|
<ellipse style="fill: #000000" cx="1212" cy="280" rx="10" ry="10"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<polyline style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" points="1033.15,280 1043.15,280 1185.99,280 1191.52,280 "/>
|
||||||
|
<polyline style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" points="1183.76,285 1193.76,280 1183.76,275 "/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<rect style="fill: #ffffff" x="527" y="72" width="182.05" height="68"/>
|
||||||
|
<rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="527" y="72" width="182.05" height="68"/>
|
||||||
|
<text font-size="12.8" style="fill: #000000;text-anchor:middle;font-family:sans-serif;font-style:normal;font-weight:normal" x="618.025" y="93.9">
|
||||||
|
<tspan x="618.025" y="93.9">Scheduling Policies/Rules</tspan>
|
||||||
|
<tspan x="618.025" y="109.9">+</tspan>
|
||||||
|
<tspan x="618.025" y="125.9">Rules solver</tspan>
|
||||||
|
</text>
|
||||||
|
<line style="fill: none; fill-opacity:0; stroke-width: 1; stroke: #000000" x1="537" y1="96.9" x2="699.05" y2="96.9"/>
|
||||||
|
<line style="fill: none; fill-opacity:0; stroke-width: 1; stroke: #000000" x1="612.65" y1="112.9" x2="623.4" y2="112.9"/>
|
||||||
|
<line style="fill: none; fill-opacity:0; stroke-width: 1; stroke: #000000" x1="579.05" y1="128.9" x2="657" y2="128.9"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<rect style="fill: #ffffff" x="787.6" y="67.1" width="351.8" height="84"/>
|
||||||
|
<rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="787.6" y="67.1" width="351.8" height="84"/>
|
||||||
|
<text font-size="12.8" style="fill: #000000;text-anchor:middle;font-family:sans-serif;font-style:normal;font-weight:normal" x="963.5" y="89">
|
||||||
|
<tspan x="963.5" y="89">Configuration of Workflow Engine</tspan>
|
||||||
|
<tspan x="963.5" y="105">(implementation, persistence, ...)</tspan>
|
||||||
|
<tspan x="963.5" y="121">+</tspan>
|
||||||
|
<tspan x="963.5" y="137">Mapping between Action types and Action Handlers</tspan>
|
||||||
|
</text>
|
||||||
|
<line style="fill: none; fill-opacity:0; stroke-width: 1; stroke: #000000" x1="856.15" y1="92" x2="1070.85" y2="92"/>
|
||||||
|
<line style="fill: none; fill-opacity:0; stroke-width: 1; stroke: #000000" x1="856.575" y1="108" x2="1070.42" y2="108"/>
|
||||||
|
<line style="fill: none; fill-opacity:0; stroke-width: 1; stroke: #000000" x1="958.125" y1="124" x2="968.875" y2="124"/>
|
||||||
|
<line style="fill: none; fill-opacity:0; stroke-width: 1; stroke: #000000" x1="797.6" y1="140" x2="1129.4" y2="140"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<polyline style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 8; stroke: #000000" points="618.025,140 618.025,197 618,197 618,205.295 "/>
|
||||||
|
<polyline style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" points="613,192.647 618,208.647 623,192.647 "/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<polyline style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 8; stroke: #000000" points="963.5,151.1 963.5,174.05 963,174.05 963,198.295 "/>
|
||||||
|
<polyline style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" points="958,185.647 963,201.647 968,185.647 "/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<polyline style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" points="110.005,280 120.005,280 148,280 153.528,280 "/>
|
||||||
|
<polyline style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" points="145.764,285 155.764,280 145.764,275 "/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<rect style="fill: #ffffff" x="193.6" y="104.1" width="174.9" height="36"/>
|
||||||
|
<rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="193.6" y="104.1" width="174.9" height="36"/>
|
||||||
|
<text font-size="12.8" style="fill: #000000;text-anchor:middle;font-family:sans-serif;font-style:normal;font-weight:normal" x="281.05" y="126">
|
||||||
|
<tspan x="281.05" y="126">Action types description</tspan>
|
||||||
|
</text>
|
||||||
|
<line style="fill: none; fill-opacity:0; stroke-width: 1; stroke: #000000" x1="203.6" y1="129" x2="358.5" y2="129"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<polyline style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 8; stroke: #000000" points="281.05,140.1 281.05,172.55 281,172.55 281,206.295 "/>
|
||||||
|
<polyline style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" points="276,193.647 281,209.647 286,193.647 "/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 12 KiB |
523
specs/mitaka/approved/watcher-add-actions-via-conf.rst
Normal file
523
specs/mitaka/approved/watcher-add-actions-via-conf.rst
Normal file
@ -0,0 +1,523 @@
|
|||||||
|
..
|
||||||
|
This work is licensed under a Creative Commons Attribution 3.0 Unported
|
||||||
|
License.
|
||||||
|
|
||||||
|
http://creativecommons.org/licenses/by/3.0/legalcode
|
||||||
|
|
||||||
|
==================================================
|
||||||
|
Provide a more dynamic Actions management solution
|
||||||
|
==================================================
|
||||||
|
|
||||||
|
Include the URL of your launchpad blueprint:
|
||||||
|
|
||||||
|
https://blueprints.launchpad.net/watcher/+spec/watcher-add-actions-via-conf
|
||||||
|
|
||||||
|
Watcher aims at providing an open solution for auditing any pool of resources
|
||||||
|
and optimizing it through recommended `Actions`_.
|
||||||
|
|
||||||
|
This blueprint aims at providing a generic and dynamic system for adding new
|
||||||
|
Optimization actions that can be used in one or several Strategies to reach
|
||||||
|
the Goal_(s) of an `Audit`_.
|
||||||
|
|
||||||
|
.. _problem_description:
|
||||||
|
|
||||||
|
Problem description
|
||||||
|
===================
|
||||||
|
|
||||||
|
Today, the set of possible `Actions`_ is fixed for a given version of Watcher
|
||||||
|
and enables optimization algorithms to include actions such as instance
|
||||||
|
migration, changing hypervisor state, changing power state (ACPI level, ...).
|
||||||
|
|
||||||
|
It should be possible to deploy and configure (in watcher.conf) new potential
|
||||||
|
Actions and associate each Action to a Python class, without the need to
|
||||||
|
redeploy a new version of Watcher.
|
||||||
|
|
||||||
|
Note that even if so far `Watcher Decision Engine`_ and `Watcher Applier`_ are
|
||||||
|
packaged in the same Python package, those services may be deployed on separate
|
||||||
|
machines. Beyond that, there will probably be a blueprint aiming at having the
|
||||||
|
`Watcher Planner`_ as a separate component (today it is included in the
|
||||||
|
Watcher Decision Engine).
|
||||||
|
|
||||||
|
This is the reason why, there should be a strong separation of concern
|
||||||
|
regarding:
|
||||||
|
|
||||||
|
* Action types definition (input parameters, ...)
|
||||||
|
* Actions instantiation of a given Action type
|
||||||
|
* Actions scheduling (through Action types scheduling policies, ...)
|
||||||
|
* Actions simulation and execution (through some Action handler class)
|
||||||
|
|
||||||
|
Each of these concerns are related to a specific `Bounded Context`_ and the
|
||||||
|
objective of this blueprint is to better address each Bounded Context
|
||||||
|
independently so that we can update the model and source code of a given
|
||||||
|
context without necessarily impacting the other contexts (Micro-Services
|
||||||
|
architecture).
|
||||||
|
|
||||||
|
Below you will find a diagram, showing the functional need regarding Actions
|
||||||
|
management in Watcher:
|
||||||
|
|
||||||
|
.. image:: ../../../doc/source/images/Watcher_Actions_Management_Functional_Need.png
|
||||||
|
:width: 140%
|
||||||
|
|
||||||
|
You can see that there is a need in Watcher for three main phases:
|
||||||
|
|
||||||
|
* The first phase named "**Define and instantiate Actions for Optimization**"
|
||||||
|
takes place in the Strategies of the Watcher Decision Engine: each
|
||||||
|
`Strategy`_ needs to be able to use and instantiate a set of pre-defined
|
||||||
|
optimization Action types in order to achieve the goal of the `Audit`_.
|
||||||
|
Those Actions are not scheduled within a timeframe at that point.
|
||||||
|
|
||||||
|
During this phase, developers need to be able to do four things in their
|
||||||
|
Strategy:
|
||||||
|
|
||||||
|
* describe and register new types of Actions, with a dedicated Domain
|
||||||
|
Specific Language (DSL). Each type of Action should have its own input
|
||||||
|
parameters, name, description, version and target `resource type`_;
|
||||||
|
* create one or several instances of these Action types (i.e. Watcher
|
||||||
|
needs some kind of factory for Actions);
|
||||||
|
* add these Actions to the recommended `Solution`_ as a simple unordered
|
||||||
|
list of Actions;
|
||||||
|
* persist this list of recommended Actions in the `Watcher Database`_.
|
||||||
|
|
||||||
|
* The second phase named "**Schedule Actions in Time**" takes place in the
|
||||||
|
Watcher Planner: the Actions instantiated in the Strategy need to
|
||||||
|
be scheduled so that they do not disturb the `SLA`_ and also because there is
|
||||||
|
some logical order when executing the Actions. For example, you will
|
||||||
|
disable an hypervisor before you start evacuating all instances from it (to
|
||||||
|
make sure that the hypervisor does not receive new initial placement request
|
||||||
|
from Nova). Therefore, the Watcher Planner must be able to take into
|
||||||
|
account some scheduling policies/rules such as:
|
||||||
|
|
||||||
|
* do not migrate too many virtual machines at the same time in order to avoid
|
||||||
|
network congestion;
|
||||||
|
* make sure there's no more virtual machines on a compute node before
|
||||||
|
powering it off (for energy saving);
|
||||||
|
* live migration is preferred to inactive migration;
|
||||||
|
* ...
|
||||||
|
|
||||||
|
As a result, during this phase of the Watcher processing, there should be an
|
||||||
|
efficient and extensible way to define those scheduling policies/rules and
|
||||||
|
there should be some implementation which can take them into account to
|
||||||
|
produce the design of a flow of Actions describing the dependency chain
|
||||||
|
between each Action (after Action A trigger Action B, ...).
|
||||||
|
|
||||||
|
Ideally, the developer should be able to integrate a new "*rules solver*"
|
||||||
|
which could be dynamically loaded in the Watcher Planner according to what
|
||||||
|
is set in Watcher configuration files.
|
||||||
|
|
||||||
|
Note that this scheduled flow of recommended Actions is what is named an
|
||||||
|
`Action Plan`_ in the Watcher vocabulary.
|
||||||
|
|
||||||
|
It should also be possible to define error recovery rules which define what
|
||||||
|
must be done whenever an error occurs in the worklow (how many attempts must
|
||||||
|
be done, how often, ...). It should be possible to define error recovery
|
||||||
|
policies for a specific Action or for a wider scope (the whole flow or
|
||||||
|
embedded flow).
|
||||||
|
|
||||||
|
Both scheduling policies/rules and the design of the flow of Actions could
|
||||||
|
rely on dedicated Domain Specific Languages (DSL) and on a specific "solver"
|
||||||
|
which would be able to take into account those rules.
|
||||||
|
|
||||||
|
Again, the developers need an easy way to persist scheduling policies/rules
|
||||||
|
and the design of the flow of Actions in the `Watcher Database`_.
|
||||||
|
|
||||||
|
* The third phase named "**Simulate and Execute Actions**" takes place in the
|
||||||
|
Watcher Applier: it consists in executing the flow of Actions built in
|
||||||
|
phase two.
|
||||||
|
This means that there should be some workflow engine system which is able to
|
||||||
|
read the flow description (described with a DSL and stored in the
|
||||||
|
Watcher Database), simulate the execution of this flow and if the
|
||||||
|
simulation is successful, really execute all the Actions it contains
|
||||||
|
in respect with the schedule (i.e. the dependency chain between Actions).
|
||||||
|
|
||||||
|
This workflow engine should be able to load the implementation (named
|
||||||
|
"**ActionHandler**") of each Action type and do the following:
|
||||||
|
|
||||||
|
* first launch some simulation method which makes sure all pre-conditions are
|
||||||
|
met before executing the real command and avoid useless rollbacks on the
|
||||||
|
real OpenStack services. The simulation phase could also make sure that all
|
||||||
|
**ActionHandler** implementations are present and that all
|
||||||
|
`target resource`_ exist.
|
||||||
|
* if pre-conditions are met, trigger some concrete command on technical
|
||||||
|
components (most of the time, it will be OpenStack components such as Nova,
|
||||||
|
Neutron,...).
|
||||||
|
* handle error recovery rules
|
||||||
|
|
||||||
|
In order to do the mapping between Action types used in phase 1 and 2 and
|
||||||
|
**ActionHandler** classes, it must be possible for developer to implement
|
||||||
|
a mapping system which would be loaded dynamically and configurable.
|
||||||
|
|
||||||
|
The workflow engine should be able to create a current context of execution
|
||||||
|
of the workflow which enables to take some output results from a previously
|
||||||
|
executed Action and inject it as input parameters of the next upcoming
|
||||||
|
Action. This context must be persisted in some database and the workflow
|
||||||
|
engine should be able to resume an interrupted workflow (in the case the
|
||||||
|
Watcher Applier service was stopped for example) from where it was
|
||||||
|
stoppped and not restart it from the zero.
|
||||||
|
|
||||||
|
Ideally, it should be possible for an operator with an admin role to browse
|
||||||
|
the history of activity of the workflow engine (especially events and alarms
|
||||||
|
regarding executed Actions).
|
||||||
|
|
||||||
|
The workflow engine should be able to send some notifications (on the Watcher
|
||||||
|
AMQP message bus) whenever the current state of an Action changes.
|
||||||
|
|
||||||
|
Use Cases
|
||||||
|
----------
|
||||||
|
|
||||||
|
As a developer.
|
||||||
|
I want to be able to create and use new optimization Actions_ in the
|
||||||
|
optimization Strategies_ (loaded in the `Watcher Decision Engine`_).
|
||||||
|
So that I can easily develop new Strategies (for a given optimization Goal_)
|
||||||
|
which rely on these actions to change the state of a managed resource and
|
||||||
|
without needing an upgrade of Watcher.
|
||||||
|
|
||||||
|
As a developer.
|
||||||
|
I want to be able to create workflows in the `Watcher Planner`_ containing
|
||||||
|
atomic actions and embedded workflows (made of several actions). Workflows may
|
||||||
|
schedule those actions in sequence or in parallel.
|
||||||
|
So that I can schedule optimization actions according to some scheduling
|
||||||
|
policies/rules.
|
||||||
|
|
||||||
|
As a developer.
|
||||||
|
I want to be able to develop scheduling policies/rules and dynamically add
|
||||||
|
those rules without needing an upgrade of Watcher.
|
||||||
|
So that I can control how actions are scheduled in a given timeframe.
|
||||||
|
|
||||||
|
As a developer.
|
||||||
|
I want to be able to provide new actions handlers as Python class which can be
|
||||||
|
loaded in the `Watcher Applier`_.
|
||||||
|
So that the Watcher Applier can launch concrete commands to the service
|
||||||
|
responsible for managing a resource (most of the time, it will be OpenStack
|
||||||
|
services such as Nova, Cinder, Neutron, ... but it can also be any resource
|
||||||
|
management service).
|
||||||
|
|
||||||
|
As an operator with an admin role.
|
||||||
|
I want to be able to easily install and configure new optimization actions
|
||||||
|
without needing to deploy a new version of the Watcher software.
|
||||||
|
So that they can be used for a new optimization Strategy that I need to
|
||||||
|
install
|
||||||
|
|
||||||
|
Project Priority
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
Not relevant because Watcher is not in the big tent so far.
|
||||||
|
|
||||||
|
Proposed change
|
||||||
|
===============
|
||||||
|
|
||||||
|
Estimated changes are going to be in the following places:
|
||||||
|
|
||||||
|
* in the `Watcher Decision Engine`_:
|
||||||
|
|
||||||
|
* in `Strategies`_
|
||||||
|
* in the `Watcher Planner`_
|
||||||
|
|
||||||
|
* in the `Watcher Applier`_
|
||||||
|
|
||||||
|
As described in the :ref:`Problem description <problem_description>`, Watcher
|
||||||
|
should integrate a new Task/Flow management system which provides a clear
|
||||||
|
separation between the three main phases:
|
||||||
|
|
||||||
|
* Define new optimization `Action`_ types and instantiate them in Strategies
|
||||||
|
* Schedule Actions in time
|
||||||
|
* Simulate and execute Actions
|
||||||
|
|
||||||
|
Alternatives
|
||||||
|
------------
|
||||||
|
|
||||||
|
We could deploy a new version of Watcher each time we need to add new Action
|
||||||
|
types but this would impact the availability of Watcher and would lead to a
|
||||||
|
much less evolutive and system.
|
||||||
|
|
||||||
|
Data model impact
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
The following data object will probably be impacted:
|
||||||
|
|
||||||
|
* **Action**:
|
||||||
|
|
||||||
|
* there may be some changes in the way we store input parameters
|
||||||
|
of an `Action`_ (probably as an array of key-value pairs) and the unique id
|
||||||
|
of the `target resource`_.
|
||||||
|
* We may also need to store in the database the list of output values
|
||||||
|
returned after the Action was executed by the Watcher Applier.
|
||||||
|
|
||||||
|
It may also be necessary to add some new data objects such as:
|
||||||
|
|
||||||
|
* **ActionType** which would contain all the information related to a certain
|
||||||
|
type of Action:
|
||||||
|
|
||||||
|
* **action_type**: the unique id of the Action type.
|
||||||
|
* **action_type_version**: the version of the Action type. It would be
|
||||||
|
provided with `SemVer`_ format.
|
||||||
|
* **parameters**: an array of input parameters provided as tuples with the
|
||||||
|
following fields: **(parameter_name, parameter_type)**. The
|
||||||
|
**parameter_type** can be any simple type such as string, integer, boolean,
|
||||||
|
float, ...
|
||||||
|
* **target_resource_type**: the unique `resource type`_ that this Action
|
||||||
|
type can change. It can be any `HEAT resource type`_.
|
||||||
|
* **display_name**: a short human readable name for the Action type.
|
||||||
|
* **display_description**: a long human readable description for the
|
||||||
|
Action type.
|
||||||
|
|
||||||
|
REST API impact
|
||||||
|
---------------
|
||||||
|
|
||||||
|
There will be an impact on every REST resource URLs that starts with
|
||||||
|
**/v1/actions/** and that uses the type **Action**:
|
||||||
|
|
||||||
|
* GET /v1/actions/(action_uuid)
|
||||||
|
* POST /v1/actions
|
||||||
|
* PATCH /v1/actions
|
||||||
|
* GET /v1/actions/detail
|
||||||
|
|
||||||
|
The type **Action** will have new attributes mentionned in the previous
|
||||||
|
paragraph.
|
||||||
|
|
||||||
|
Please look at the `Actions handling in Watcher API`_.
|
||||||
|
|
||||||
|
If Watcher stores new data objects such as **ActionType**, it would be
|
||||||
|
necessary to provide new REST resource URLs for managing those objects with
|
||||||
|
CRUD operations.
|
||||||
|
|
||||||
|
Note that for creating a new **ActionType** with the API, the user may provide
|
||||||
|
the description of this **ActionType** in a file compliant with the DSL that
|
||||||
|
will be used for it (i.e. probably a JSON or YAML file).
|
||||||
|
|
||||||
|
Security impact
|
||||||
|
---------------
|
||||||
|
|
||||||
|
In the case a new Action needs to access an OpenStack service (for example,
|
||||||
|
Neutron), the **watcher** user under which Watcher Applier is running will
|
||||||
|
need to be declared as having a role with enough rights on this service to
|
||||||
|
trigger the concrete Action.
|
||||||
|
|
||||||
|
Notifications impact
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
Other end user impact
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
Aside from the API, here are there other ways a user will interact with this
|
||||||
|
feature:
|
||||||
|
|
||||||
|
* impact on **python-watcherclient**:
|
||||||
|
|
||||||
|
* will need to find a new way to display the list of Actions and the
|
||||||
|
detailed information about an Action.
|
||||||
|
* will need to be able to handle new data objects such as **ActionType** as
|
||||||
|
well
|
||||||
|
|
||||||
|
Performance Impact
|
||||||
|
------------------
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
Other deployer impact
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
When delivering a new `Strategy`_, the operator will deploy the following
|
||||||
|
softwares:
|
||||||
|
|
||||||
|
* the main Python class implementing the `Strategy`_;
|
||||||
|
* the files containing the description of the needed `Actions`_ types (written
|
||||||
|
in whatever DSL is appropriate for this);
|
||||||
|
* the files containing the description of the scheduling rules (written in
|
||||||
|
whatever DSL is appropriate for this);
|
||||||
|
* the Python Planner class (Rules solver) that will be able to read the
|
||||||
|
scheduling rules and generate a schedule of the Actions. Note that this is
|
||||||
|
optional to deliver a new class here because the new Strategy may rely on
|
||||||
|
a previously deployed Rules solver;
|
||||||
|
* the Python classes of each Actions handler needed in the Actions flow
|
||||||
|
to simulate/execute in the Watcher Applier.
|
||||||
|
|
||||||
|
The operator will also need to change the Watcher configuration in order to
|
||||||
|
indicate:
|
||||||
|
|
||||||
|
* What `Watcher Planner`_ implementation will be used for scheduling Actions
|
||||||
|
* What **Watcher Actions Mapper** implementation will be used to do the mapping
|
||||||
|
between Action types and Action handlers (i.e. Python class loaded by the
|
||||||
|
`Watcher Applier`_).
|
||||||
|
* What implementation of the Workflow engine must be used to simulate and
|
||||||
|
execute the Actions flow.
|
||||||
|
* What storage backend will be used by the Workflow engine used in the
|
||||||
|
Watcher Applier to persist the current state of the Actions flow.
|
||||||
|
|
||||||
|
Developer impact
|
||||||
|
----------------
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
|
||||||
|
Implementation
|
||||||
|
==============
|
||||||
|
|
||||||
|
Assignee(s)
|
||||||
|
-----------
|
||||||
|
|
||||||
|
Primary assignee:
|
||||||
|
jed56
|
||||||
|
|
||||||
|
Work Items
|
||||||
|
----------
|
||||||
|
|
||||||
|
The Watcher team should first study whether solutions like `TaskFlow`_ or
|
||||||
|
`Mistral`_ would fit the need. It would certainly avoid long rewriting of
|
||||||
|
source code and would even help us anticipate the future needs regarding
|
||||||
|
the management/scheduling of `Actions`_ in Watcher.
|
||||||
|
|
||||||
|
Here is the list of foreseen work items:
|
||||||
|
|
||||||
|
* Find an appropriate Domain Specific Language (DSL) for describing a new
|
||||||
|
Action type in Watcher.
|
||||||
|
* Implement the factory which is able to instantiate Actions in the
|
||||||
|
`Strategy`_ according to the Action type description.
|
||||||
|
* Put the `Watcher Planner`_ classes in a dedicated Python package (not in
|
||||||
|
the `Watcher Decision Engine`_)
|
||||||
|
* Add a dynamic loading of the Watcher Planner implementation (via
|
||||||
|
stevedore)
|
||||||
|
* Find a generic format to persist the description of the flow of Actions that
|
||||||
|
will be generated by the `Watcher Planner`_ and loaded by the
|
||||||
|
`Watcher Applier`_
|
||||||
|
* Provide a default implementation of the `Watcher Planner`_. This default
|
||||||
|
implementation should be very simple and based on priority associated to each
|
||||||
|
Action. Later, more complex implementations can be provided which would be
|
||||||
|
able to read scheduling rules DSL. We may have to benchmark several existing
|
||||||
|
Rules solver implementations.
|
||||||
|
* Add a dynamic loading of Actions handlers in the Watcher Applier (via
|
||||||
|
stevedore).
|
||||||
|
* Integrate an existing Workflow engine which would be able to load and execute
|
||||||
|
Actions handlers according to the design of the Actions flow produced
|
||||||
|
by the Watcher Planner (i.e. what is called the `Action Plan`_)
|
||||||
|
* Add a simulation phase in the Watcher Applier in order to verify that
|
||||||
|
the Actions flow can be executed without errors.
|
||||||
|
* Make sure errors are handled correctly whenever an Action fails during the
|
||||||
|
simulation phase or during the real execution of the Actions flow in the
|
||||||
|
Watcher Applier.
|
||||||
|
|
||||||
|
|
||||||
|
Dependencies
|
||||||
|
============
|
||||||
|
|
||||||
|
There are some dependencies with the following blueprints:
|
||||||
|
|
||||||
|
* In blueprint named "`Code refactoring using terms defined in our glossary`_",
|
||||||
|
some classes related to this specification (meta-action, primitive, ...) will
|
||||||
|
be renamed or moved to another package.
|
||||||
|
* We have to consider the existence of existing workflow management frameworks
|
||||||
|
such as `TaskFlow`_: see blueprint
|
||||||
|
https://blueprints.launchpad.net/watcher/+spec/use-taskflow
|
||||||
|
|
||||||
|
We should also have a look to other existing workflow management frameworks:
|
||||||
|
|
||||||
|
* `Mistral`_: this OpenStack project proposes a Workflow as a service system
|
||||||
|
* `PyUtilib`_: it's a self contained workflow engine, intended to be embedded
|
||||||
|
and developed to automate the processing of scientific workflows.
|
||||||
|
* `Spiff Workflow`_: a workflow engine implemented in pure Python
|
||||||
|
* `hurry.workflow`_: a simple workflow system. It can be used to implement
|
||||||
|
stateful multi-version workflows for Zope Toolkit applications.
|
||||||
|
|
||||||
|
Testing
|
||||||
|
=======
|
||||||
|
|
||||||
|
Unit tests will be needed for:
|
||||||
|
|
||||||
|
* the loading of the files containing the description of the needed `Actions`_
|
||||||
|
types (written in whatever DSL is appropriate for this);
|
||||||
|
* the loading of files containing the description of the scheduling rules
|
||||||
|
(written in whatever DSL is appropriate for this);
|
||||||
|
* the Python Planner class (Rules solver) that will be able to read the
|
||||||
|
scheduling rules and generate a schedule of the Actions;
|
||||||
|
* the dynamic loading of an Action handler class inside the
|
||||||
|
`Watcher Applier`_;
|
||||||
|
* the Python classes of each Actions handler needed in the Actions flow
|
||||||
|
to simulate/execute in the Watcher Applier;
|
||||||
|
* the dynamic loading of a `Watcher Planner`_ implementation;
|
||||||
|
* the dynamic loading of a **Watcher Actions Mapper** implementation;
|
||||||
|
* the execution of the default provided Watcher Planner implementation
|
||||||
|
* the execution of the default provided **Watcher Actions Mapper**
|
||||||
|
implementation;
|
||||||
|
* the configuration of different storage backends for the Workflow engine used
|
||||||
|
in the Watcher Applier to persist the current state of the Actions
|
||||||
|
flow.
|
||||||
|
* the execution of a simulation phase and the error management during this
|
||||||
|
simulation phase
|
||||||
|
|
||||||
|
It will also be necessary to validate the whole Action management system in
|
||||||
|
the existing integration tests.
|
||||||
|
|
||||||
|
|
||||||
|
Documentation Impact
|
||||||
|
====================
|
||||||
|
|
||||||
|
The documentation will have to be updated, especially the glossary, in order to
|
||||||
|
explain the new concepts regarding `Actions`_ definition, scheduling and
|
||||||
|
execution.
|
||||||
|
|
||||||
|
The architecture description will also need to be updated because:
|
||||||
|
|
||||||
|
* the `Watcher Planner`_ will become independent from the
|
||||||
|
`Watcher Decision Engine`_
|
||||||
|
* a new component will be introduced: the **Watcher Actions Mapper**
|
||||||
|
* many component implementations will be provided as plugins (Action types,
|
||||||
|
Watcher Planner, **Watcher Actions Mapper**, **ActionHandler**)
|
||||||
|
|
||||||
|
The documentation regarding Watcher installation and configuration will also
|
||||||
|
need to be updated in order to explain:
|
||||||
|
|
||||||
|
* howto describe new Action types with the proposed DSL;
|
||||||
|
* howto deploy new Action types into Watcher;
|
||||||
|
* howto use new Action types in your optimization strategy (i.e. howto
|
||||||
|
instantiate an Action from a given Action type);
|
||||||
|
* howto add new scheduling policies/rules in the `Watcher Planner`_;
|
||||||
|
* howto build flows of Actions using the proposed DSL;
|
||||||
|
* howto add a new Watcher Planner implementation;
|
||||||
|
* howto add a new **Watcher Actions Mapper** implementation;
|
||||||
|
* howto configure the `Watcher Applier`_: engine implementation, persistence
|
||||||
|
backend, ...
|
||||||
|
|
||||||
|
References
|
||||||
|
==========
|
||||||
|
|
||||||
|
IRC discussions:
|
||||||
|
|
||||||
|
* Action point related to `TaskFlow`_: http://eavesdrop.openstack.org/meetings/watcher/2015/watcher.2015-12-09-13.59.html
|
||||||
|
* A lot of exchanges regarding Actions and Workflow management in the Git
|
||||||
|
reviews related to the Watcher glossary: https://review.openstack.org/#/c/246370/
|
||||||
|
|
||||||
|
|
||||||
|
History
|
||||||
|
=======
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
|
||||||
|
.. _Actions handling in Watcher API: https://factory.b-com.com/www/watcher/doc/watcher/webapi/v1.html#actions
|
||||||
|
.. _SemVer: http://semver.org/
|
||||||
|
.. _stevedore: https://pypi.python.org/pypi/stevedore
|
||||||
|
.. _TaskFlow: https://wiki.openstack.org/wiki/TaskFlow
|
||||||
|
.. _Mistral: https://wiki.openstack.org/wiki/Mistral
|
||||||
|
.. _PyUtilib: https://software.sandia.gov/trac/pyutilib
|
||||||
|
.. _Spiff Workflow: https://github.com/knipknap/SpiffWorkflow/wiki
|
||||||
|
.. _hurry.workflow: https://pypi.python.org/pypi/hurry.workflow
|
||||||
|
.. _potential Action states: https://factory.b-com.com/www/watcher/doc/watcher/glossary.html#action
|
||||||
|
.. _Action: https://factory.b-com.com/www/watcher/doc/watcher/glossary.html#action
|
||||||
|
.. _Actions: https://factory.b-com.com/www/watcher/doc/watcher/glossary.html#action
|
||||||
|
.. _Action Plan: https://factory.b-com.com/www/watcher/doc/watcher/glossary.html#action-plan
|
||||||
|
.. _Audit: https://factory.b-com.com/www/watcher/doc/watcher/glossary.html#audit
|
||||||
|
.. _Solution: https://factory.b-com.com/www/watcher/doc/watcher/glossary.html#solution
|
||||||
|
.. _SLA: https://factory.b-com.com/www/watcher/doc/watcher/glossary.html#sla
|
||||||
|
.. _Strategy: https://factory.b-com.com/www/watcher/doc/watcher/glossary.html#strategy
|
||||||
|
.. _Strategies: https://factory.b-com.com/www/watcher/doc/watcher/glossary.html#strategy
|
||||||
|
.. _Watcher Applier: https://factory.b-com.com/www/watcher/doc/watcher/architecture.html#watcher-applier
|
||||||
|
.. _Watcher Decision Engine: https://factory.b-com.com/www/watcher/doc/watcher/architecture.html#watcher-decision-engine
|
||||||
|
.. _Watcher Planner: https://factory.b-com.com/www/watcher/doc/watcher/glossary.html#watcher-planner
|
||||||
|
.. _Watcher Database: https://factory.b-com.com/www/watcher/doc/watcher/architecture.html#watcher-database
|
||||||
|
.. _resource type: https://factory.b-com.com/www/watcher/doc/watcher/glossary.html#managed-resource-type
|
||||||
|
.. _target resource: https://factory.b-com.com/www/watcher/doc/watcher/glossary.html#managed-resource
|
||||||
|
.. _Code refactoring using terms defined in our glossary: https://blueprints.launchpad.net/watcher/+spec/glossary-related-refactoring
|
||||||
|
.. _Bounded Context: http://martinfowler.com/bliki/BoundedContext.html
|
||||||
|
.. _HEAT resource type: http://docs.openstack.org/developer/heat/template_guide/openstack.html
|
||||||
|
.. _goal: https://factory.b-com.com/www/watcher/doc/watcher/glossary.html#goal
|
@ -81,6 +81,8 @@ class TestTitles(testtools.TestCase):
|
|||||||
code_block = True
|
code_block = True
|
||||||
if "http://" in line or "https://" in line:
|
if "http://" in line or "https://" in line:
|
||||||
continue
|
continue
|
||||||
|
if line.startswith("..") and "image::" in line:
|
||||||
|
continue
|
||||||
# Allow lines which do not contain any whitespace
|
# Allow lines which do not contain any whitespace
|
||||||
if re.match("\s*[^\s]+$", line):
|
if re.match("\s*[^\s]+$", line):
|
||||||
continue
|
continue
|
||||||
|
Loading…
Reference in New Issue
Block a user