Compare commits

...

586 Commits

Author SHA1 Message Date
Jenkins
ecb0e218a9 Merge "add Ocata release notes" 2017-01-26 15:41:02 +00:00
Jenkins
4228647d15 Merge "Add period input parameter to basic strategy" 2017-01-26 15:35:11 +00:00
Antoine Cabot
4f1d758a40 add Ocata release notes
Change-Id: Iff0c7601f6ea1b35de1afb1d71b8aff08a967eab
2017-01-26 14:03:12 +00:00
Jenkins
b4433db20a Merge "Fix invalid mock on ceilometerclient" 2017-01-26 13:54:48 +00:00
Hidekazu Nakamura
e03f56e7c7 Add period input parameter to basic strategy
This patch set adds new period strategy input parameter
which allows allows to specify the time length of
statistic aggregation.

Partial-Bug: #1614021

Change-Id: I1a276206e5b2c05d8f94acdeb866c8822fa84f35
2017-01-26 16:50:07 +03:00
Vincent Françoise
d925166a25 Fix invalid mock on ceilometerclient
The mocks on _get_alarm_client() are now failing because it was renamed
as _get_redirect_client(). This fix reflects this name change.

Change-Id: Id61e74dc4adc0c939661462953b322d65104a651
2017-01-26 10:42:30 +01:00
Jenkins
4a5d8cf709 Merge "Remove obsolete Resource element" 2017-01-25 13:54:39 +00:00
Jenkins
e3c6db11c6 Merge "Graph cluster model instead of mapping one" 2017-01-25 13:54:27 +00:00
Jenkins
840d422b01 Merge "Fix building of model with a scoped exclusion rule" 2017-01-25 11:59:42 +00:00
OpenStack Proposal Bot
e9d8a2882f Updated from global requirements
Change-Id: I82bcbf318a846a94c3d61eb49e3769387738692f
2017-01-24 20:03:01 +00:00
Alexander Chadin
6e09cdb5ac New Applier Workflow Engine
This patch set allows to execute Watcher Actions in parallel.
New config option max_workers sets max number of threads
to work.

Implements: blueprint parallel-applier
Change-Id: Ie4f3ed7e75936b434d308aa875eaa49d49f0c613
2017-01-24 18:26:22 +00:00
Vincent Françoise
edd3d219d5 Remove obsolete Resource element
Partially Implements: blueprint graph-based-cluster-model

Change-Id: I2765d1c7a864d6658c847dcd988314fc8f11049c
2017-01-24 18:26:11 +00:00
Vincent Françoise
d433d6b3c8 Graph cluster model instead of mapping one
In this changeset, I use https://review.openstack.org/#/c/362730/
as an example to make the existing ModelRoot fully graph-based.

Change-Id: I3a1ec8674b885d75221035459233722c18972f67
Implements: blueprint graph-based-cluster-model
2017-01-24 18:26:06 +00:00
David TARDIVEL
c5d4f9cb40 Fix building of model with a scoped exclusion rule
If we define an audit scope with a exclusion rule composed
with compute nodes, the compute model built is empty. I fix
the algo used to built this scoped compute model.

Change-Id: I675226c58474b7ea52b3f92e7b466adae40643b8
Closes-bug: #1658995
2017-01-24 18:25:13 +00:00
Vincent Françoise
41f579d464 Fix broken gates because of wrong pip command
Change-Id: I7d8cb4bfa7962819b7298149e94f06be44f2670e
2017-01-24 18:12:15 +01:00
Jenkins
1a2fa9addf Merge "Update configuration document" 2017-01-23 13:35:27 +00:00
Jenkins
9e5ca76116 Merge "Fix test_clients_monasca failure" 2017-01-23 13:31:00 +00:00
Jenkins
fa63b2a2b3 Merge "Updated from global requirements" 2017-01-23 13:30:54 +00:00
Jenkins
22cad5651e Merge "Fix bad CDMC update on reception of service.update" 2017-01-23 13:30:33 +00:00
Jenkins
a912977336 Merge "resolve KeyError exception" 2017-01-23 13:29:27 +00:00
licanwei
2d7a375338 Fix test_clients_monasca failure
'cafile','certfile','keyfile' and 'insecure'
 need mock override.

Change-Id: I289904ed38f22d4475fe04f2005b795d07cb8d83
Closes-Bug: #1658553
2017-01-23 10:57:08 +08:00
OpenStack Proposal Bot
45b82e1898 Updated from global requirements
Change-Id: I4378e3c39766f70456ae633e49390fd8244bde88
2017-01-21 15:59:07 +00:00
Jenkins
926dbc8392 Merge "New default planner" 2017-01-19 14:08:40 +00:00
Alexander Chadin
0e440d37ee New default planner
Co-Authored-By: Vincent Francoise <Vincent.FRANCOISE@b-com.com>
Change-Id: Ide2c8fc521488e486eac8f9f89d3f808ccf4b4d7
Implements: blueprint planner-storage-action-plan
2017-01-19 13:16:57 +03:00
Jenkins
66934f29d3 Merge "Should use glanceclient to get images" 2017-01-18 10:05:54 +00:00
Jenkins
7039a9d247 Merge "Updated from global requirements" 2017-01-17 13:39:49 +00:00
Jenkins
bbbae0b105 Merge "Fix dummy strategy to use input parameters" 2017-01-17 13:39:43 +00:00
Jenkins
1d08d2eea1 Merge "Modify the field in tox.ini" 2017-01-17 10:19:56 +00:00
zhuzeyu
23442a4da6 Modify the field in tox.ini
We use 'genconfig' field to generate configuration file generally.

TrivialFix

Change-Id: I152613103594dd7bcbc8b7f53a12e223a25bb051
2017-01-17 18:01:56 +08:00
Jenkins
ed88b436af Merge "Add action plan SUPERSEDED state" 2017-01-17 09:59:09 +00:00
David TARDIVEL
a48a16596f Add action plan SUPERSEDED state
An action plan can be now go to SUPERSEDED state if another
action plan is on going for instance. It could be the case with
tempest test, because we can have several scenario tests running
at the same time.

Change-Id: I5449e545676463f0ea601e67993e9dffa67929a7
Closes-bug: #1657031
2017-01-17 09:41:19 +01:00
Hidekazu Nakamura
8f4a856bd2 Fix dummy strategy to use input parameters
Dummy strategy does not use input parameters.
This patch fixes it.

Change-Id: I9aa0414869e6f2d52dca5cea6055ff81067448ef
2017-01-17 09:01:26 +09:00
OpenStack Proposal Bot
85a46ce4d4 Updated from global requirements
Change-Id: Id0dc6c33430a3691986acf8604ff67d8b2ae9a24
2017-01-16 17:30:38 +00:00
David TARDIVEL
35066dfe60 Update Server Consolidation global efficacy
As instance migration cost is petty compared to the cost of
compute node release, I update the way to compute the global
efficacy for a server consolidation goal. The new formula is simplest
and it's only based on compute node.

Change-Id: Ibcce31a85af70429f412c96c584a761d681366a2
2017-01-16 16:56:24 +01:00
Jenkins
fc9eb6e995 Merge "Multi datasource support for Basic Consolidation" 2017-01-16 09:54:24 +00:00
Jenkins
aaf6fd7959 Merge "Added Monasca Helper" 2017-01-16 09:54:02 +00:00
Cao Xuan Hoang
5e077f37ea Fix a typo in watcher/objects/base.py
Removed redundant 'the'

Change-Id: I03cd038c7b1a5d266cb9a1264adc3902c23c971c
2017-01-16 11:18:57 +07:00
licanwei
2ec8bc10cd resolve KeyError exception
In the optimize solution stage when launching audit
based vm_workload_consolidation strategy.
The instance map in node should change when migration
action was removed. Otherwise a KeyError exception
will be thrown.

Change-Id: I054b6b12922892a02d155b4ddc001b19890d32c5
Closes-Bug: #1656157
2017-01-14 11:21:42 +08:00
Jenkins
89cea83c85 Merge "Add auto_trigger support to watcher" 2017-01-13 17:07:29 +00:00
David TARDIVEL
2dd00a2037 Enable notification for vm task state update
Add a script command to enable Nova compute.instance.update
notifications on VM and task state changes.

Change-Id: I639f003d92e184085a332f53c6783e5eca0002fe
2017-01-13 10:42:24 +01:00
Kevin_Zheng
59e13fd1f3 Should use glanceclient to get images
Getting images from Novaclient is refered as proxy API
and was deprecated to use in nova. We should use
Glanceclient to get images instead.

Closes-bug: #1655516
Change-Id: Ie7d89e857d149e11b3c9b44c980b0be5cb0cc35f
2017-01-13 02:07:04 +00:00
Vincent Françoise
4235ef7c24 Multi datasource support for Basic Consolidation
In this changeset, I added the support for both Monasca and
Ceilometer for the basic_consolidation strategy.

Partially Implements: blueprint monasca-support

Change-Id: Ide98550fbf4a29954e46650190a05be1b8800317
2017-01-12 17:51:59 +01:00
Vincent Françoise
a015af1bd2 Added Monasca Helper
In this changeset, I implemented a Helper class to deal with
Monasca requests.

Change-Id: I14cfab2c45451b8bb2ea5f1f48254b41fa5abae8
Partially-Implements: blueprint monasca-support
2017-01-12 17:51:58 +01:00
avnish
dad90b63fd Removed unnecessary utf-8 encoding
Change-Id: I967f933abd6c49f4262d39c2f406405a9ef18b16
2017-01-11 15:23:06 +05:30
Jenkins
c6e5f98008 Merge "Enable coverage report in console output" 2017-01-11 09:00:18 +00:00
OpenStack Proposal Bot
1341c0ee02 Updated from global requirements
Change-Id: I31678175f4e6cb5b55e45714b058ad548ce50ca9
2017-01-01 12:18:37 +00:00
Jeremy Liu
6e99fcffc3 Enable coverage report in console output
Change-Id: Iaba796a4126b2e106af5b4688cd6c94559a42a64
2016-12-30 16:37:24 +08:00
Jenkins
a57f54ab8f Merge "multinode devstack update for live-migration" 2016-12-28 16:51:38 +00:00
Jenkins
d1490e3fa7 Merge "Fix TypeError if no input_parameters added" 2016-12-27 16:21:12 +00:00
Jenkins
1324baf9f5 Merge "Add additional depencencies of CentOS 7" 2016-12-27 09:27:29 +00:00
Hidekazu Nakamura
0adc7d91e6 Fix TypeError if no input_parameters added
By calling solution.add_action with no input_parameters, TypeError:
'NoneType' object does not support item assignment was occurred.
This patch fix it.

Change-Id: Ia2ad0c18bc20468ca73c0ab70495fac2c90e0640
Closes-Bug: #1647927
2016-12-27 13:49:54 +09:00
Hidekazu Nakamura
0d7ded0bb3 Update configuration document
In this changeset, Adding admin role to watcher user of
admin project is removed.

Change-Id: Icc8167b12ec0669045d100f8b9ea94d2ac08837d
2016-12-27 13:01:50 +09:00
Hidekazu Nakamura
80dfbd6334 Add additional depencencies of CentOS 7
In this changeset, additional dependencies of CentOS 7 is added.

Change-Id: Ie513448ae39b9c006360792732a967d337775d8b
2016-12-27 09:35:36 +09:00
licanwei
7d40b3d4c3 Fix reference http
<http://docs.openstack.org/admin-guide-cloud/
telemetry-measurements.html> ==>
<http://docs.openstack.org/admin-guide/telemetry-measurements.html>

Change-Id: Iea22902db12b9bb05b9cd2d9a4ac95818f00f133
2016-12-26 16:07:12 +08:00
Jenkins
cedf70559e Merge "Updated from global requirements" 2016-12-20 09:33:21 +00:00
Jenkins
cc561c528f Merge "Fix variable name error" 2016-12-20 09:27:31 +00:00
鲍昱蒙00205026
87b494d52a remove incorrect inline comment
Change-Id: I4f5b48a07e146c727ebf724d1993633aa707cec8
2016-12-20 09:25:41 +08:00
Alexander Chadin
d0bca1f2ab Add auto_trigger support to watcher
This patch set adds support of auto-triggering of action plans.

Change-Id: I36b7dff8eab5f6ebb18f6f4e752cf4b263456293
Partially-Implements: blueprint automatic-triggering-audit
2016-12-19 12:37:26 +03:00
licanwei
068178f12a Fix variable name error
doc/source/dev/plugin/cdmc-plugin.rst
'collector' should be 'dummy_collector'

Change-Id: I2f8f7107faa4b1f707f424b696c9bc3c6d7e22f4
2016-12-19 11:36:41 +08:00
OpenStack Proposal Bot
99e6c4aebb Updated from global requirements
Change-Id: I2f191bc9e9316dfb2d029624a0c8773a576de004
2016-12-17 21:40:43 +00:00
Jenkins
b446f8afd2 Merge "Fix some incorrect description in doc." 2016-12-16 17:06:42 +00:00
Jenkins
7783ebfb71 Merge "Fix method name in doc/source/dev/plugin/action-plugin.rst" 2016-12-16 17:02:41 +00:00
Jenkins
22cfc495f4 Merge "Improve the instruction of vm_workload_consolidation." 2016-12-16 16:38:45 +00:00
Jenkins
360b0119d6 Merge "remove unused log" 2016-12-16 16:38:35 +00:00
OpenStack Proposal Bot
48fc90d7b6 Updated from global requirements
Change-Id: I8ffe399bda77a605f97c5128957b07d405ac5169
2016-12-16 13:49:28 +00:00
Jenkins
c5ff387ae9 Merge "Repair log parameter error" 2016-12-16 09:55:54 +00:00
David TARDIVEL
1bc6b0e605 Fix bad CDMC update on reception of service.update
When we receive a incoming 'service.update' notification
from nova, with disabled: false, we should set the related
compute node status to ENABLED.

Change-Id: Ib8075a5cf786f81ec41423805433f83ae721cbbd
Closes-bug: #1650485
2016-12-16 10:11:38 +01:00
Jenkins
345083e090 Merge "Function call pass parameter error" 2016-12-16 08:47:55 +00:00
Prudhvi Rao Shedimbi
695ddf8ae7 Implemented clients and auth config module
Implemented clients and auth config module

Implements: blueprint centralise-config-opts

Change-Id: I28ea8376aa34114331cbae61596839ebae6cf7eb
2016-12-14 20:13:23 +00:00
Jenkins
8fd5057cd0 Merge "Implemented wacther decision engine config module" 2016-12-14 18:48:14 +00:00
Jenkins
3db81564f4 Merge "Documentation for Uniform Airflow Migration Strategy Fixed issues" 2016-12-14 17:51:11 +00:00
Jenkins
10066ed8fd Merge "Documentation for Workload Balance Migration Strategy Fixed comments and added the doc primitive call" 2016-12-14 17:51:04 +00:00
Jenkins
e4c5f4f050 Merge "update strategy table when parameters_spec changes" 2016-12-14 17:48:27 +00:00
Prudhvi Rao Shedimbi
53c896dd24 Implemented wacther decision engine config module
Implemented wacther decision engine config module

Partially Implements: blueprint centralise-config-opts

Change-Id: Ie4e9dd7d902fa85044d1859974cbd75d54c8b6cc
2016-12-14 17:40:57 +00:00
Susanne Balle
40a46c6663 Documentation for Uniform Airflow Migration Strategy
Fixed issues

Closes-Bug: #1623486
Change-Id: If303283949ef39a26c91bbff7b4664e81687d169
2016-12-14 11:01:27 -05:00
Prudhvi Rao Shedimbi
ed21e452e0 Implemented applier config module
Implemented applier config module

Partially Implements: blueprint centralise-config-opts

Change-Id: I237596b06dc3bee318414346cfa58ae4cb81079b
2016-12-14 15:50:11 +00:00
Prudhvi Rao Shedimbi
80e77a5b81 Implemented planner config module
Implemented planner config module

Partially Implements: blueprint centralise-config-opts

Change-Id: I4d710c8552ef211c6a9c38dd8f5515f68a6d36c4
2016-12-14 14:52:37 +00:00
Prudhvi Rao Shedimbi
74112dd7cf Implemented db config module
Implemented db config module

Partially Implements: blueprint centralise-config-opts. Also moved
basedir_def, bindir_def and state_path_def to watcher.conf.paths

Change-Id: I73d201f6a23bbdb1c6189434b11314a66620e85c
2016-12-14 15:13:31 +01:00
Prudhvi Rao Shedimbi
9e4bf718da Implemented exception config module
Implemented exception config module

Partially Implements: blueprint centralise-config-opts

Change-Id: Ic1b94e28a960a7306f15afbf69382edc15b5999e
2016-12-14 11:05:01 +00:00
Prudhvi Rao Shedimbi
5c79074e9c Implemented paths config module
Implemented paths config module

Partially Implements: blueprint centralise-config-opts

Change-Id: I2b779fb1ce552567feac678cb5bd78aad0d53d52
2016-12-14 10:56:58 +00:00
Jenkins
ac6848dad3 Merge "Implemented utils config module" 2016-12-14 10:31:07 +00:00
Jenkins
648715eb5c Merge "Implemented api config module" 2016-12-14 10:20:48 +00:00
licanwei
1a17c4b7ac remove unused log
remove unused log

Change-Id: Iad207a708388ecf940d502ef8f5f64d5cc8ff80e
2016-12-14 15:18:02 +08:00
licanwei
c4dfbd5855 Repair log parameter error
Multi-parameters should form a dict type

Change-Id: Ia883de6a0e34cebd28ba7fb0ecd105acb6cf2830
2016-12-14 14:24:20 +08:00
Amy Fong
1981f3964e multinode devstack update for live-migration
For multinode setup, a couple of updates to /etc/nova/nova.conf was
needed for live migration.

serial_console needed to be disabled and vncserver_listen needed to
be set to any for the vncserver to accept connections from all of the
compute nodes.

Change-Id: I62ebc2a07ca525bd80da130981f337806b2b89ae
Closes-Bug: #1649638
2016-12-13 12:31:51 -05:00
Jenkins
3b5ef5d625 Merge "Specific exception for stale cluster state was added." 2016-12-13 15:35:41 +00:00
Jenkins
7fd486bd65 Merge "Unnecessary exception" 2016-12-13 12:00:23 +00:00
Jenkins
3cf4b315d3 Merge "improve statistic_aggregation" 2016-12-13 11:02:21 +00:00
licanwei
d792e3cfae Function call pass parameter error
add_migration(self, instance_uuid, source_node,
                      destination_node, model)
param source_node: node object
param destination_node: node object

but in optimize_solution(), The incoming parameters are
source_node_uuid and destination_node_uuid.
This causes an exception:
AttributeError: 'unicode' object has no attribute 'state'

Change-Id: Ia27f219caa007f2b49ff9efc2544d5b4d894fe65
Closes-Bug: #1649441
2016-12-13 16:44:30 +08:00
Susanne Balle
25d84ba662 Documentation for Workload Balance Migration Strategy
Fixed comments and added the doc primitive call

Closes-Bug: #1623486

Change-Id: I704536530c576de702434008aa30a7fbbaddff25
2016-12-12 14:17:08 -05:00
Anton Khaldin
7908af3150 Specific exception for stale cluster state was added.
Specific exception should be thrown when cluster state
is stale. Current usage is to raise this exception if
compute_model.state is True.
Bug was describeid by Jean-Emile DARTOIS.

Change-Id: Iaddb4cc8007c51bb14759c9da829751e834499d0
Closes-Bug: #1621855
2016-12-12 18:04:51 +00:00
Prudhvi Rao Shedimbi
04fdea2aa0 Implemented utils config module
Implemented utils config module

Partially Implements: blueprint centralise-config-opts

Change-Id: Ic09ecba60022b69ec4031608716e34209d3fe578
2016-12-12 16:36:04 +00:00
Jenkins
cee9cfb62c Merge "Updated from global requirements" 2016-12-12 13:31:35 +00:00
Jenkins
e1912fe03e Merge "Modify the variable assignment errors" 2016-12-12 11:57:57 +00:00
licanwei
d859f3ac1f Fix CI failures
reference to:
http://osdir.com/ml/openstack-dev/2016-12/msg00420.html
/nova/tox.ini

Change-Id: Ie566f4b7c1c3cd3c1654281c0cad028c3886d9f7
2016-12-12 18:01:25 +08:00
licanwei
7a72371df8 improve statistic_aggregation
improve statistic_aggregation

Change-Id: Ic1fb19780fa4a39c5eb74e5ed30db0e4c06d0e09
2016-12-12 17:10:38 +08:00
licanwei
82bb097e9f Unnecessary exception
If the instance state is not ACTIVE,
There is no need to throw an exception.

Change-Id: I88ba3ae9c92b75ed57fc9647e33c4a10801b2c18
Closes-Bug: #1648309
2016-12-08 15:06:26 +08:00
licanwei
a9ef9f3a94 update strategy table when parameters_spec changes
At present, In the sync function, there is no check about the
parameters_spec field in strategy table, if the parameters_spec
field content has changed, Such as increased 'periods' parameter,
strategy table will not be updated, the program will run abnormal.

exception msg:
2016-12-05 11:11:39.138 TRACE watcher.decision_engine.audit.base
raise AttributeError(name)
2016-12-05 11:11:39.138 TRACE watcher.decision_engine.audit.base
AttributeError: periods

Change-Id: I84709c246acbdf44ccac257b07a74084962bb628
Closes-Bug: #1647521
2016-12-08 13:34:03 +08:00
Prudhvi Rao Shedimbi
8e7ba3c44a Implemented api config module
Implemented api config module

Partially Implements: blueprint centralise-config-opts

Change-Id: I055618e546bb1bfa2c1764bcff1a1f94e5adea96
2016-12-07 21:46:28 +00:00
OpenStack Proposal Bot
9a2ca8c4b7 Updated from global requirements
Change-Id: Ib5668cd281665477968b5a9acadf65765b5a06a1
2016-12-07 13:41:44 +00:00
Jenkins
c08666b2fa Merge "[Doc] Fix example code of goal plugin" 2016-12-07 12:26:50 +00:00
OpenStack Proposal Bot
6638f921a3 Updated from global requirements
Change-Id: Idceb803efc01b3b2346cc15391517e4b527d43ac
2016-12-07 09:09:52 +00:00
zte-hanrong
f66eb463ca Improve the instruction of vm_workload_consolidation.
The goal of "vm_consolidation" is not existent by default.

Use the goal of "server_consolidation" instead for shell command.

Change-Id: Icef5536a337fa88a4504e23e4de6d2e96c45d7b6
2016-12-07 16:50:51 +08:00
Hidekazu Nakamura
6a323ed54f Fix method name in doc/source/dev/plugin/action-plugin.rst
precondition -> pre_condition
postcondition -> post_condition

Change-Id: Ia8edc9b428c14ea35225cbbe1a54b67a33151a64
2016-12-07 15:50:51 +09:00
licanwei
1f2a854d6a Repairing unit test failures
If fieldname is 'deleted', field.type.python_type raise
NotImplementedError.

Change-Id: I47246ce9a3b0c8d2a3ea44e825d9604f5b14ed38
Closes-Bug: #1647574
2016-12-06 17:15:19 +08:00
ericxiett
d252d47cc0 Fix some incorrect description in doc.
doc/source/deploy/configuration.rst
* 'The Watcher system is a collection of services
that provides support to optimize your IAAS plateform. '

Fix: Typo, plateform -> platform

* Additionally, the Bare Metal service has certain
external dependencies, which are very similar to
other OpenStack services:

Fix: Bare Metal -> Watcher

* Please check your hypervisor configuration to correctly
handle instance migration.

Fix: ref of ``instance migration`` is http://docs.openstack.org/
admin-guide/compute-live-migration-usage.html

Change-Id: I00ab282a0f9ffcfddf745df1dd67418a43d70b10
Closes-Bug: #1646290
2016-12-06 04:00:18 +08:00
Hidekazu Nakamura
d0e46d81fc [Doc] Fix example code of goal plugin
An example code of goal plugin does not work.
This patch fixes it.

Change-Id: I75c2ffa74a003fad9e2d512927e4cb47554783c2
2016-12-02 12:47:34 +09:00
Jenkins
4e240b945b Merge "Fix one ref that does not work." 2016-11-30 11:43:28 +00:00
Jenkins
e09188d862 Merge "Updated from global requirements" 2016-11-30 11:42:39 +00:00
Jenkins
a4b1df2fce Merge "Fix rally gate test" 2016-11-30 11:32:46 +00:00
Jenkins
22933e4d79 Merge "Show team and repo badges on README" 2016-11-30 10:39:46 +00:00
Jenkins
40a5c98382 Merge "Use uuidutils instead of uuid.uuid4()." 2016-11-30 08:43:49 +00:00
Jenkins
5b21b9a17e Merge "Fix 'ImportError' when docbuild." 2016-11-30 08:42:47 +00:00
Jenkins
02d1850be7 Merge "Add periods input parameter" 2016-11-30 08:34:19 +00:00
Jenkins
5f1f10e3d3 Merge "Documentation for Outlet Temperature Based Strategy Fixed outstanding comments" 2016-11-30 08:20:43 +00:00
zhuzeyu
e4732e1375 Use uuidutils instead of uuid.uuid4().
Change-Id: I3f734b6c4d252f8eb73a49b447fd89e5e444002f
Closes-Bug: #1082248
2016-11-29 14:15:54 +08:00
licanwei
715f6fa1cd Modify the variable assignment errors
The values of 'released_compute_nodes_count' and
'instance_migrations_count' are upside down

Change-Id: I0662bdfce575de529eb8c12363be7fa196b1a88c
2016-11-29 10:20:23 +08:00
Flavio Percoco
6daa09f489 Show team and repo badges on README
This patch adds the team's and repository's badges to the README file.
The motivation behind this is to communicate the project status and
features at first glance.

For more information about this effort, please read this email thread:

http://lists.openstack.org/pipermail/openstack-dev/2016-October/105562.html

To see an example of how this would look like check:

https://gist.github.com/fb14a4269de717e9410ba91722027512

Change-Id: If7f9b36d45c431ecb6d0eb76d907d63573de4238
2016-11-25 17:21:54 +01:00
ericxiett
7feced419c Fix 'ImportError' when docbuild.
There is not module 'messaging.utils' in 'watcher.common'
but module 'synchronization' instead.

Change-Id: If2d585a4f416614cbe91e4ef61fc7473508d38af
Closes-Bug: #1643862
2016-11-24 01:34:51 +08:00
ericxiett
3319748367 Fix one ref that does not work.
One space was missed between 'the' and ':ref' in
'the:ref:Watcher Database <watcher_database_definition>'.

Change-Id: I3e46121dc7c30f73df4ca455e2c629929cdbd2ec
Closes-Bug: #1644388
2016-11-24 01:15:56 +08:00
OpenStack Proposal Bot
a84f52dfe3 Updated from global requirements
Change-Id: Id8935a3139541edb1dae894358f20c3cfc0ddd21
2016-11-23 11:05:56 +00:00
Jenkins
3f8e4451f5 Merge "Fix some typos in action.py & action_plan.py & audit.py" 2016-11-23 09:41:59 +00:00
Jenkins
d082c9ac41 Merge "Fix the wrong ref for 'Compute node'" 2016-11-23 09:41:09 +00:00
Jenkins
9080180309 Merge "Fix inconsistent descriptions in docstring in action_plan.py" 2016-11-23 08:59:25 +00:00
Jenkins
55893043df Merge "Solve some spelling mistakes." 2016-11-23 08:58:58 +00:00
Jenkins
19074f615a Merge "Remove redundan lines." 2016-11-23 08:58:49 +00:00
Alexander Chadin
295c8d914c Add periods input parameter
This patch set adds new periods strategy input
parameter that allows to specify the time length of
statistic aggregation.

Change-Id: Id6c7900e7b909b0b325281c4038e07dc695847a1
2016-11-23 11:55:14 +03:00
zte-hanrong
99735fa39a Solve some spelling mistakes.
Change-Id: Id7e8c4efbfc4203e63583b68c87be75f4a195b66
2016-11-23 11:40:51 +08:00
zte-hanrong
b80229f3d0 Remove redundan lines.
Change-Id: Iac10aea306e59eb91b192ec6e89f42851d9548a5
2016-11-23 11:31:26 +08:00
Susanne Balle
5e9ba463ee Documentation for Outlet Temperature Based Strategy
Fixed outstanding comments

Closes-Bug: #1623486

Change-Id: I2d327f472749c0e5a8b184eb426abebd757cc4f7
2016-11-21 11:15:01 -05:00
Jenkins
120c116655 Merge "[Doc] Fix default value in workload_stabilization" 2016-11-21 13:45:41 +00:00
Jenkins
c9cfd3bfbd Merge "Replaces uuid.uuid4 with uuidutils.generate_uuid()" 2016-11-21 13:36:21 +00:00
Jenkins
31f2b4172e Merge "Change hardware.cpu_util in workload_stabilization" 2016-11-21 13:32:23 +00:00
Hidekazu Nakamura
5151b666fd Change hardware.cpu_util in workload_stabilization
In this change set, hardware.cpu_util is changed to
compute.node.cpu.percent in workload_stabilization.
By doing so, one can run this strategy on a simple devstack
without having to setup the SNMP plugin.

Change-Id: I8df8921337ea3f4e751c0c822d823e64e3ca7e1c
2016-11-21 09:58:38 +09:00
YumengBao
578138e432 Fix inconsistent descriptions in docstring in action_plan.py
Change-Id: I4e74ac0ce7bdd17f1809ac1fbb8bf8110bfa290e
2016-11-19 17:58:46 +08:00
Jenkins
7e2fd7ed9a Merge "Removed nullable flag from audit_id in ActionPlan" 2016-11-18 14:40:53 +00:00
Vincent Françoise
74cb93fca8 Removed nullable flag from audit_id in ActionPlan
Partially Implements: blueprint watcher-versioned-objects

Change-Id: I0bf572e0756ef5d9bb73711a28225526dd044995
2016-11-18 14:16:32 +01:00
qinchunhua
876f3adb22 Replaces uuid.uuid4 with uuidutils.generate_uuid()
Change-Id: I38740842402841ae446603faacbbe969854f2396
Closes-Bug: #1082248
2016-11-18 00:55:39 +00:00
Vincent Françoise
06682fe7c3 Fixed update of WatcherObject fields on update
I this changeset, I fixed the issue whereby object auto fields are not
being updated within the WatcherObject after an update.

Change-Id: I7e65341b386a5c0c58c2109348e39e463cf2f668
Closes-Bug: #1641955
2016-11-17 17:41:13 +01:00
zhangyanxian
eaaa2b1b69 Fix some typos in action.py & action_plan.py & audit.py
Change-Id: I64909a6319a709dd8cb6a0e6b28bca714f5b4f6e
TrivialFix: "occured" should be "occurred"
2016-11-17 11:20:58 +00:00
Hidekazu Nakamura
88187a8ba9 [Doc] Fix default value in workload_stabilization
In this change set, Default value 'hardware.cpu_util' of instance_metrics
was changed to 'compute.node.cpu.percent'.

Change-Id: I02f87e5fea663e2e04c61cc36b7d55ff250bf8cc
2016-11-17 10:39:10 +09:00
ericxiett
0b6979b71c Fix the wrong ref for 'Compute node'
The refo of 'Compute node' in glossary.rst is wrong.
And modify it.

Change-Id: I3be61c95df2d538c5e49f169c428a605816d66e0
Closes-Bug: #1641405
2016-11-17 09:13:42 +08:00
Jenkins
3ebe8ab70f Merge "Added Tempest API tests for /scoring_engines" 2016-11-16 21:16:25 +00:00
Jenkins
240f849758 Merge "Implemented base + moved plugins & service conf" 2016-11-16 17:24:45 +00:00
Jenkins
46f23fac57 Merge "Add audit.planner events" 2016-11-16 16:52:13 +00:00
Jenkins
83ea0bff45 Merge "Add audit.strategy events" 2016-11-16 16:50:13 +00:00
Vincent Françoise
46f511a8c8 Implemented base + moved plugins & service conf
In this changeset, I implemented the main logic although this is
mainly a shameful copy/paste of Nova's blueprint
https://blueprints.launchpad.net/nova/+spec/centralize-config-options

Partially Implements: blueprint centralise-config-opts

Change-Id: Ib645ad5da5c706336bb6ac37e85b027d05665c32
2016-11-16 17:45:07 +01:00
Jenkins
2c5be7c974 Merge "Implemented audit.delete notification" 2016-11-16 16:43:43 +00:00
Jenkins
081ec077ad Merge "Implemented audit.create notification" 2016-11-16 16:43:37 +00:00
Jenkins
f32206d845 Merge "Implemented audit.update notification" 2016-11-16 16:43:31 +00:00
Jenkins
e476384425 Merge "Update devstack plugin to add notification param" 2016-11-16 16:42:36 +00:00
Jenkins
822fe78675 Merge "Added notification_level config option" 2016-11-16 16:30:18 +00:00
Jenkins
6fabfe2af1 Merge "Removed status_topic config parameter" 2016-11-16 16:30:13 +00:00
Jenkins
982a49b952 Merge "Remove stale notification code" 2016-11-16 16:27:09 +00:00
Jenkins
19da978a1c Merge "Added notifications documentation page" 2016-11-16 15:35:27 +00:00
Jenkins
f4bced5a79 Merge "Added support for versioned notifications" 2016-11-16 15:31:45 +00:00
Jenkins
168537a754 Merge "Added Model base class + related doc" 2016-11-16 13:55:06 +00:00
Vincent Françoise
25da1636b1 Add audit.planner events
In this changeset, I implemented the following notifications:

- audit.planner.start
- audit.planner.end
- audit.planner.error

Partially Implements: blueprint audit-versioned-notifications-api

Change-Id: I29d371f8cb3fd7948c87bec97186e24a88e8fdb6
2016-11-16 13:59:00 +01:00
Vincent Françoise
19fe0a0c56 Add audit.strategy events
In this changeset, I implemented the following notifications:

- audit.strategy.start
- audit.strategy.end
- audit.strategy.error

Partially Implements: blueprint audit-versioned-notifications-api

Change-Id: I6ae8468caf8d215bc8bc694813beb4dc94f53fdb
2016-11-16 13:59:00 +01:00
Vincent Françoise
6f9f67cacc Implemented audit.delete notification
In this changeset, I implemented the audit.delete notification.

Partially Implements: blueprint audit-versioned-notifications-api

Change-Id: I8aeb73f4b8d3273d6de7dc9c44674e3041b005ea
2016-11-16 13:59:00 +01:00
Vincent Françoise
0c0a9c84d6 Implemented audit.create notification
In this changeset, I implemented the audit.create notification.

Change-Id: Ia092ca3a3dc951e3313a07f15a98aec5818e9ab0
Partially-Implements: blueprint audit-versioned-notifications-api
2016-11-16 13:59:00 +01:00
Vincent Françoise
9405eb0806 Implemented audit.update notification
In this changeset, I implemented the sending of update notifications
whenever an audit is modified.

Change-Id: I5ccc2516ce896ae7d4ef542b133e8f052eaed602
Partially-Implements: blueprint audit-versioned-notifications-api
2016-11-16 13:59:00 +01:00
Vincent Françoise
54c45a2738 Update devstack plugin to add notification param
In this changeset, I updated the devstack plugin so it has the
necessary configuration options for it to emit the Watcher
notifications straight out of the box.

Partially Implements: blueprint watcher-notifications-ovo

Change-Id: I048e0b82cde40bd3699c90429bdf55ee235fff3b
2016-11-16 13:57:25 +01:00
Vincent Françoise
4bebf882d9 Added notification_level config option
In this changeset, I implemented the notification_level parameter
that allows you to set the level minimum level of notification to
be emitted by Watcher.

Partially Implements: blueprint watcher-notifications-ovo

Change-Id: I78b30ceb3ee7606078a87beb3a4ce5d9568af1e0
2016-11-16 13:57:25 +01:00
Vincent Françoise
cdda06c08c Removed status_topic config parameter
In this changeset, I removed the now obsolete status_topic config
option.

DocImpact
Partially Implements: blueprint watcher-notifications-ovo

Change-Id: Icfc03abd875b77fc456bfa286ac2b5774651e8fa
2016-11-16 13:57:25 +01:00
Vincent Françoise
395ccbd94c Remove stale notification code
In this changeset, I cleaned up the Watcher codebase to remove
the old notification mechanism that is actually unused.

Partially Implements: blueprint watcher-notifications-ovo

Change-Id: I1901e65f031441b98a7d6f6c9c1c0364eaaaf481
2016-11-16 13:57:25 +01:00
Vincent Françoise
cdee2719f7 Added notifications documentation page
In this changeset, I added a new Sphinx directive (from Nova) that
allows us to automatically display notification samples for of
all the upcoming notifications in Watcher.

Partially Implements: blueprint watcher-notifications-ovo

Change-Id: Id7d819ee21db6dc616c78faea483b883f77e3bd6
2016-11-16 13:57:25 +01:00
Vincent Françoise
b27e5b91b9 Added support for versioned notifications
In this changeset, I added all the required modification in order
for Watcher to enable the implementation of versioned notifications.

Change-Id: I600ecbc767583824555b016fb9fc7faf69c53b39
Partially-Implements: blueprint watcher-notifications-ovo
2016-11-16 13:57:25 +01:00
Jenkins
9dc3fce3e5 Merge "Add doc for vm_workload_consolidation strategy" 2016-11-16 09:34:06 +00:00
Bruno Grazioli
5c793894ab Add doc for vm_workload_consolidation strategy
This patch adds documentation on requirements for
vm_workload_consolidation strategy.

Change-Id: I304644138b34658b09f7cd8f29eb089757807b61
Closes-bug: #1640820
2016-11-16 09:26:31 +01:00
Alexander Chadin
8eb99ef76e Fix rally gate test
This patch set removes extra field from rally tasks
since Watcher team has removed extra field from
watcher and python-watcherclient projects.

Change-Id: Ib1640cbe8668f56f3a3a54e9f73bb1e3e6747d79
2016-11-16 11:26:27 +03:00
OpenStack Proposal Bot
3532c74001 Updated from global requirements
Change-Id: If8e1f5591d026572e8fdd187ab737801a58b9a88
2016-11-15 19:39:39 +00:00
Jenkins
c0b17105af Merge "Add doc for workload-stabilization spec" 2016-11-15 10:53:58 +00:00
Jenkins
22c424cecb Merge "optimized 'find_instance()'" 2016-11-15 10:08:21 +00:00
Jenkins
01118b72c7 Merge "Remove unused SUBMITTED audit state" 2016-11-14 15:09:57 +00:00
Alexander Chadin
9761207d8a Add doc for workload-stabilization spec
This patch set adds how-to-use documentation for
Watcher Overload standard deviation algorithm.

Change-Id: I75d7cd0ff8507ca70efb6d9668ae9fbf651a7f97
2016-11-14 18:07:11 +03:00
Jenkins
abd93a298e Merge "Fix the typo in efficacy_indicator module" 2016-11-14 14:00:30 +00:00
Jenkins
71c21c3e41 Merge "Use oslo_log instead of logging" 2016-11-14 13:53:19 +00:00
Jenkins
a487718fdc Merge "Added action_plan ObjectField for Action" 2016-11-14 10:10:10 +00:00
Jenkins
b8dddfcf67 Merge "Added audit & strategy ObjectField for ActionPlan" 2016-11-14 10:10:04 +00:00
Jenkins
2a6a96640a Merge "Added goal & strategy ObjectField for Audit" 2016-11-14 10:09:58 +00:00
Jenkins
e7d70cd279 Merge "Added goal+strategy ObjectField for AuditTemplate" 2016-11-14 10:09:02 +00:00
ericxiett
72c9d86094 Fix the typo in efficacy_indicator module
Modify typo 'gobal' to 'global'.

Change-Id: Ib8b4c65d64d767666ea1a32bc72b66559a035c5f
Closes-Bug: #1641408
2016-11-13 22:49:15 +08:00
Alexander Chadin
5e9a2f6fa6 Fix NoMetricValuesForInstance error
This patch set allows in case of NoMetricValuesForInstance exception
to continue the flow of Workload Stabilization strategy
instead of interrupting.

Closes-Bug: #1640096
Change-Id: I2de22bb97defb9c34e409102d06846275793b80d
2016-11-11 12:01:28 +03:00
howardlee
b6e17a8bc8 Use oslo_log instead of logging
1. the use of the log in the module should be unified.
2. oslo_log wrapped logging.

Change-Id: Iac48fcbcd2fc9a7002fed6a328dc74242ad770de
2016-11-10 19:22:25 +08:00
licanwei
3e392b07bf optimized 'find_instance()'
The function nova.servers.list() will return a huge context in the
large infrastructure. We can use nova.servers.get() instead of it.

Change-Id: If922c31e8aff27bfbc475c63083ee561ee7f1f67
2016-11-10 19:17:46 +08:00
Jenkins
21abbb4cd1 Merge "Added 'goal' ObjectField for Strategy object" 2016-11-10 09:38:04 +00:00
Jenkins
a539ef8c58 Merge "Refactored Watcher objects to use OVO" 2016-11-10 09:37:58 +00:00
Jenkins
0c29946590 Merge "Removed deadline, version, extra & host_aggregate" 2016-11-10 09:37:52 +00:00
Jenkins
be0a889327 Merge "Eager loading on One-to-X foreign keys" 2016-11-10 09:26:41 +00:00
Hidekazu Nakamura
ea7e6a7c94 Fix workload stabilization strategy to ignore disabled hosts
Change-Id: Ib5244da196111fac03b1ac4b756a59ad15deb778
Closes-Bug: #1640102
2016-11-10 15:55:55 +09:00
Vincent Françoise
090d5d1f1e Added Tempest API tests for /scoring_engines
In this changeset, I added tempest tests for the scoring engine
endpoint.

Change-Id: I7f36250eb9df437b518d20fd4f2e1feb223f3c82
2016-11-09 16:35:31 +05:30
Jaewoo Park
4973dd6bf6 Remove unused SUBMITTED audit state
Submitted state is not referenced nor used in the Watcher codebase,
and hence removed the references to the state from the codebase.

Change-Id: Ibb0cf5125e2d93683739abf35030b7cf5cb1b056
Closes-Bug: 1634150
2016-11-07 13:16:31 -08:00
Jenkins
ad7ae3e676 Merge "[Doc] Fix strategy list optional argument" 2016-11-07 16:11:58 +00:00
Jenkins
7ed7aade91 Merge "Added missing test on GMR plugin" 2016-11-07 14:50:13 +00:00
Jenkins
1fbc8b57bf Merge "Transform KB into MB and normalize CPU" 2016-11-07 14:24:44 +00:00
Vincent Françoise
b4b17ba395 Added action_plan ObjectField for Action
In this changeset, I added the "action_plan" ObjectField which can
either be loaded by setting the new "eager" parameter as True
or not loaded (as before) by setting it to False. The advantage of
introducing this eager parameter is that this way,
we can reduce to a minimum the overhead of DB queries whenever the
related object fields is not actually needed.

Change-Id: Iae255d9a0a919e2b6db710be24dbf9033b72166e
Partially-Implements: blueprint watcher-versioned-objects
2016-11-07 10:40:07 +01:00
Vincent Françoise
060c369838 Added audit & strategy ObjectField for ActionPlan
In this changeset, I added the "audit" and the "strategy "ObjectField
which can either be loaded by setting the new "eager" parameter as True
or not loaded (as before) by setting it to False.
The advantage of introducing this eager parameter is that this way,
we can reduce to a minimum the overhead of DB queries whenever the
related object fields is not actually needed.

Change-Id: Ieca6fa438cbf2267f5ae2ea0d059b2953e65076b
Partially-Implements: blueprint watcher-versioned-objects
2016-11-07 10:40:07 +01:00
Vincent Françoise
f9df54c555 Added goal & strategy ObjectField for Audit
In this changeset, I added the "goal" and the "strategy "ObjectField
which can either be loaded by setting the new "eager" parameter as True
or not loaded (as before) by setting it to False.
The advantage of introducing this eager parameter is that this way,
we can reduce to a minimum the overhead of DB queries whenever the
related goal is not actually needed.

Change-Id: I5a1b25e395e3d904dae954952f8e0862c3556210
Partially-Implements: blueprint watcher-versioned-objects
2016-11-07 10:39:20 +01:00
Vincent Françoise
54cf10b41c Added goal+strategy ObjectField for AuditTemplate
In this changeset, I added the "goal" and the "strategy "ObjectField
which can either be loaded by setting the new "eager" parameter as True
or not loaded (as before) by setting it to False.
The advantage of introducing this eager parameter is that this way,
we can reduce to a minimum the overhead of DB queries whenever the
related goal is not actually needed.

Change-Id: I97418163f68aea2f1cda80be94e4035f0b3700ae
Partially-Implements: blueprint watcher-versioned-objects
2016-11-07 10:39:20 +01:00
Vincent Françoise
f54aca70cc Added 'goal' ObjectField for Strategy object
In this changeset, I added the "goal" ObjectField which can
either be loaded by setting the new "eager" parameter as True or
not loaded (as before) by setting it to False.
The advantage of introducing this eager parameter is that this way,
we can reduce to a minimum the overhead of DB queries whenever the
related goal is not actually needed.

Partially-Implements: blueprint watcher-versioned-objects
Change-Id: I103c9ed161d2cedf7b43c55f9e095ef66bf44dea
2016-11-07 10:39:20 +01:00
Vincent Françoise
fc31dae7f2 Refactored Watcher objects to use OVO
In this changeset, I modified all existing Watcher objects to now
rely on oslo.versionedobjects as a base.

Change-Id: I3c9b1ca6da529d128743b99020350f28926ea1a2
Partially-Implements: blueprint watcher-versioned-objects
2016-11-07 10:39:19 +01:00
Vincent Françoise
ed95d621f4 Removed deadline, version, extra & host_aggregate
As we are about to version the Watcher objects, we need to make sure
that upcoming model/object modifications are additive in order to
avoid having to bump the major version of the API. Therefore,
this changeset removes 4 unused DB fields that were exposed in their
associated Watcher objects (i.e. AuditTemplate and Audit).

Change-Id: Ifb0783f21cd66db16b31e3c8e376fc9d6c07dea3
Partially-Implements: blueprint watcher-versioned-objects
2016-11-07 10:39:19 +01:00
Vincent Françoise
750e6bf213 Eager loading on One-to-X foreign keys
In this changeset, I added ORM relationships to the DB models
concerning the already-declared foreign keys.
I also modified the DB query building to now handle a new 'eager'
parameter that, if True, is responsible to also fetch the data
relative to these 'parent' DB entities (no cascading).

Change-Id: Ieea181af9a4b173c54621dcc6c549161f5a35aeb
Partially-Implements: blueprint watcher-versioned-objects
2016-11-07 10:37:14 +01:00
Hidekazu Nakamura
afdfd8161f [Doc] Fix strategy list optional argument
Optional argument --goal-uuid changed to --goal.
This patch fixes it.

Change-Id: I79dedc94d6437eda0363da91b5065724e22bc1c8
2016-11-04 16:29:34 +09:00
Atul Pandey
aae3f79fef Use Enum value instead of String Value
Fixing Gating Issue.

Change-Id: I64a0df9e27e09172119a3a8f5395204b7476f23d
2016-11-02 10:32:57 +00:00
Jenkins
86f4f6a979 Merge "Change "Openstack" to "OpenStack"" 2016-10-26 08:50:14 +00:00
liyanhang
b48b881c20 Change "Openstack" to "OpenStack"
According to the word choice convention in
http://docs.openstack.org/contributor-guide/writing-style/word-choice.html
We should use OpenStack instead of Openstack.

Change-Id: I4300305eabc8d7cfe0072e5ac345dab63303558c
2016-10-25 13:07:26 +00:00
qinchunhua
e681645a54 Avoid use xx=[] for parameter to initialize it's value
This patch is deprecated use xx = [] for the parameter initial value,
this parameter will only be initialized at the first call,this is not
what we expected.
Better choice is to set the initial value to None,
then initialize xx with xx= xx or [] in method body.

More details:http://effbot.org/zone/default-values.htm

Change-Id: Iee0648fd500422f48c3f7f35b5066fdc644ae308
2016-10-25 12:47:36 +00:00
Jenkins
111e04d5c3 Merge "Updated from global requirements" 2016-10-18 10:04:46 +00:00
Jenkins
26424ee670 Merge "Remove duplicate unittest" 2016-10-18 09:46:42 +00:00
Jenkins
a95b73f3bb Merge "Fix typo in docstring" 2016-10-18 09:46:34 +00:00
Alexander Chadin
ef0d133ba8 Transform KB into MB and normalize CPU
This patch set normalizes CPU for hardware.cpu.util meter and
transform KB into MB fetched from hardware.memory.used meter.

Change-Id: I6dd1d053e81f06c3adb6fb256ac77bbf55a07f3e
2016-10-18 11:21:18 +03:00
OpenStack Proposal Bot
40f98bfd07 Updated from global requirements
Change-Id: Ib8ad24fbf57fbbabc7224d2e2c203cf4aeee0bfb
2016-10-17 15:52:45 +00:00
Jenkins
10bf74041b Merge "Add strategy template doc" 2016-10-17 13:47:56 +00:00
Jenkins
b9969d4854 Merge "Fix typo in hooks.py" 2016-10-17 08:50:04 +00:00
Jenkins
989d9807e8 Merge "Test code tidy up" 2016-10-17 08:49:59 +00:00
Jenkins
751d5a00d0 Merge "Delete python bytecode file" 2016-10-17 08:49:49 +00:00
Jenkins
cc44e2a0c0 Merge "Drop MANIFEST.in - it's not needed by pbr" 2016-10-17 08:49:43 +00:00
Jenkins
0139d8537c Merge "Add service object to the watcher_db_schema" 2016-10-17 08:49:35 +00:00
qinchunhua
35e6565183 Delete python bytecode file
This patch delete python bytecode including
pyo before every test run.

Change-Id: Ie6406337072bebaaa94a2b5437a2c1cece107b56
2016-10-15 00:57:02 -04:00
Jenkins
ebc70a46db Merge "Add Audit Scope Handler" 2016-10-14 15:01:20 +00:00
David TARDIVEL
3de2d368c0 Add strategy template doc
Developer should provide a detailled documentation about his strategy
algorithm to make it even easier to use by a Watcher end user.
I propose in this changeset a template for strategy documentation.
you will find also a example with basic consolidation strategy.

Change-Id: I66da1a33b87a94b508dd23ac7dce4cae6f4e068b
2016-10-13 15:30:11 +00:00
Iswarya_Vakati
6331274708 Drop MANIFEST.in - it's not needed by pbr
watcher already uses PBR:-
setuptools.setup(
    setup_requires=['pbr>=1.8'],
    pbr=True)

This patch removes `MANIFEST.in` file as pbr generates a
sensible manifest from git files and some standard files
and it removes the need for an explicit `MANIFEST.in` file.

Change-Id: If1b80738e28d71fd9e9bb4939f94adfd721a041a
Closes-Bug:#1608980
2016-10-13 18:16:44 +05:30
Jenkins
ff81f237a7 Merge "Moved Watcher doc plugin outside main package" 2016-10-13 08:42:09 +00:00
Alexander Chadin
48cc6b2718 Add Audit Scope Handler
This patch set adds audit scope mechanism.
It also removes host_aggregate field.

Change-Id: Ia98ed180a93fc8c19599735e2b41471d322bae9a
Partially-Implements: blueprint define-the-audit-scope
2016-10-13 10:50:58 +03:00
Alexander Chadin
c34a1acbea Add service object to the watcher_db_schema
This patch set adds service object to the watcher_db_schema_diagram.txt
New watcher_db_schema_diagram.png is compiled and attached.

Partially-Implements: blueprint watcher-service-list
Change-Id: Ibaac9020b0cb9fb147259a8685a7a072216ff95d
2016-10-12 12:53:11 +00:00
Alexander Chadin
e7a1e148ca Add service supervisor
This patch set adds supervisor mechanism for Watcher services
to get ability to track states.

Partially-Implements: blueprint watcher-service-list
Change-Id: Iab1cefb971c79ed27b22b6a5d1bed8698e35f9a4
2016-10-12 15:52:06 +03:00
Jenkins
6cf796ca87 Merge "Added composite unique name constraints" 2016-10-12 12:45:53 +00:00
Jenkins
4f6d42e26a Merge "Updated from global requirements" 2016-10-12 12:13:06 +00:00
Jenkins
c3aac66add Merge "Stop adding ServiceAvailable group option" 2016-10-12 12:12:55 +00:00
OpenStack Proposal Bot
0a7a9e9ab4 Updated from global requirements
Change-Id: Ib9ba6bcb305584db7675db73850dee844e2e2c66
2016-10-11 19:17:31 +00:00
Vincent Françoise
3129f31208 Added Model base class + related doc
In this changeset I added a Model abtract base class for models
and updated the plugin docs to reference it. I also added the
CDM and CDMC acronyms to the glossary.

Change-Id: Ie7d76a9f84d545715fa6e5bf350b9d2321bab9e1
2016-10-11 17:48:14 +02:00
licanwei
cd2cd184eb Add RECOMMENDED state
The state of RECOMMENDED also can change to CANCELLED
state by Adminstrator.

Change-Id: Ia6a117367451e6fb35a55acfcbf0fb788063ea4b
2016-10-09 15:43:10 +08:00
Andreas Jaeger
f1a2de4138 Enable release notes translation
Releasenote translation publishing is being prepared. 'locale_dirs'
needs to be defined in conf.py to generate translated version of the
release notes.

Note that this repository might not get translated release notes - or
no translations at all - but we add the entry here nevertheless to
prepare for it.

Change-Id: I67b2202570e23d3f20f7d132b7d7dbb460a2af3f
2016-10-06 20:56:44 +02:00
Vincent Françoise
10cbcd2432 Added composite unique name constraints
In this changeset, I added composite contraints on models that
were currently subject to an implicit uniqueness.
This composite constraint takes as an input the name and the deleted
columns.
The 'deleted' column is 0 by default and is updated with the value of
the associated 'id' column upon soft deletion.
What this means is that this composite constraint guarantees the fact
that we can hold many soft deleted records holding the exact same name.
Indeed, the value of the deleted column will be different whilst
forbidding 2 non-soft deleted records with the same name as their
associated 'deleted' value will be 0 and subsequently violates the
constraint.

Change-Id: I3ee39e23aa4ca9bc6b4ea9af8c6b7e6d67af0136
2016-10-06 16:59:41 +02:00
Jenkins
431b54fb4c Merge "Watcher utils cleanup" 2016-10-05 15:50:11 +00:00
Vincent Françoise
f2e5702657 Added missing test on GMR plugin
The show_models() function was not covered by any test so this
changeset is adding a new unit test for it.

Change-Id: Ia861f049c1f1ee0aa623404e62fb002392c9052d
2016-10-05 15:41:56 +02:00
Vincent Françoise
96357aec04 Moved Watcher doc plugin outside main package
In this changeset, I renamed watcher/doc.py file as
doc/ext/term.py which subsequently does not get scanned for coverage
anymore. Hence, we can close this bug.

Change-Id: I9d700da6569b464ce71085fe78002521555002b9
Closes-bug: #1527163
2016-10-05 15:22:50 +02:00
Jenkins
eb0da97ea6 Merge "Updated from global requirements" 2016-10-04 16:36:36 +00:00
Nishant Kumar
631e1398a1 Stop adding ServiceAvailable group option
Service available group already exists.Therefore we don't need to
register this group here again.

Change-Id: I2096ed1f69a1f70fbf248fee5fded94e3caca6c6
Closes-Bug: #1621036
2016-10-04 20:48:11 +05:30
haris tanvir
db3b5b30b2 HasLength() rewritten to assertEqual()
HasLength() based assertions are re-written to assertEqual() based
assertion to homogenize the test code base.

For example:

assertThat(.., HasLength()) becomes assertEqual(len(),...)

Change-Id: Ia3bf24e34fffe445ff4b0ee61fb7cbc0eb36a57a
Closes-Bug:#1629898
2016-10-04 12:35:38 +05:00
OpenStack Proposal Bot
74acf2a3f2 Updated from global requirements
Change-Id: I19710f88c213dd34ed2d3bf75e208d6bfe206c0c
2016-10-03 14:17:48 +00:00
Jenkins
2642627da6 Merge "Docstrings should not start with a space" 2016-10-03 06:33:58 +00:00
Jenkins
09861a0d20 Merge "Fix capital letter in doc" 2016-10-03 06:31:03 +00:00
Jenkins
dddd29b04a Merge "Doc updates" 2016-09-28 16:12:40 +00:00
Ha Van Tu
abe37390ae Fix typo in docstring
This patch replaces typo "applicatin" by "application".

Change-Id: I3c117920966fcc4400ee30c368b61180b983dd8b
2016-09-28 12:06:44 +07:00
licanwei
8b37bef12d Remove duplicate unittest
In tests/api/test_hooks.py
the 'test_hook_without_traceback_debug'
and 'test_hook_without_traceback_debug_tracebacks'
have the same function.

Change-Id: I5209bc8b1251b77b7444d51531c3902529d11453
2016-09-28 10:47:03 +08:00
Jenkins
d3d85c4801 Merge "Fixed issue on compute nodes iteration" 2016-09-27 08:20:58 +00:00
zhangyanxian
0f9361ee6c Fix typo in hooks.py
TrivialFix

Change-Id: Iff206110433b9cd76a1a2b7c6475267a9c7a568c
2016-09-27 06:33:20 +00:00
Cao Xuan Hoang
c8d605984f Docstrings should not start with a space
As per OpenStack Docstrings guide lines [1]:
[H401] Docstrings should not start with a space.

[1] http://docs.openstack.org/developer/hacking/#docstrings

trivialfix

Change-Id: Ifdff563f3ab7559e68c7201575045013db7383a5
2016-09-27 13:01:12 +07:00
Jenkins
a5b485ae29 Merge "Refactored Tests to load scenarios from file" 2016-09-26 16:31:24 +00:00
Jenkins
0e4bae9391 Merge "Add constraint target to tox.ini and remove 1 dep" 2016-09-26 09:41:29 +00:00
Ha Van Tu
e7888b2844 Fix capital letter in doc
This patch replaces 'english' by 'English' in the Watcher doc.

Change-Id: I2de7100fbbbb4de5d2d6f9575c116986aa37982a
2016-09-26 16:10:37 +07:00
Vincent Françoise
d0ea20e4bc Doc updates
Updated inconsistent docs.

Change-Id: I4be05f662fee6ebdf721ac93dd97611b5a686273
2016-09-26 09:58:44 +02:00
Vincent Françoise
55591cce43 Watcher utils cleanup
As some of our utils function are actually available in oslo.utils,
this patchset simply gets rid of our local copy and instead references
the oslo.utils one. This will help us deport the code maintenance of
these to a 3rd party library.

Change-Id: I3760ebab69d35c37bbe78500918d4e46b5bd9119
2016-09-23 11:12:26 +02:00
Jenkins
21b3ac173a Merge "Fixed GMR configuration issue" 2016-09-21 14:37:42 +00:00
Jenkins
35a1ee7670 Merge "Fix typo in docstring from "interprete" to "interpret"" 2016-09-21 14:11:28 +00:00
Vincent Françoise
5112f294c8 Fixed GMR configuration issue
GMR was ignoring the config because the conf wasn't passed when
starting any of the Watcher services. This changeset fixes this issue.

Change-Id: If386c5f0459c4278a2a56c8c3185fcdafce673a0
2016-09-21 15:43:44 +02:00
Jenkins
28970d0512 Merge "Fix a typo in watcher.po" 2016-09-21 13:05:58 +00:00
David TARDIVEL
83d06cef5f Add constraint target to tox.ini and remove 1 dep
This adds a pip install command to tox.ini that is only used when the
tox env is passed with the 'constraints' factor appended onto it.
As such this will not effect developer workflows or current unit tests.

The initial use of this will be in a non-voting job, to verify that the
constrained checks with tox are stable.  DevStack is already running
constrained jobs, as such problems are no expected.

To run a tox with pip using constraints on a developer system a
developer should run the desired tox environment with -constraints.
For example: $(tox -epy27-constraints)
Pip will pull the current version of the upper-constraints.txt file down
from the git.openstack.org, however this method can be overriden to use
a local file setting the environment variable "UPPER_CONSTRAINTS_FILE"
to the local path or a different URL, it is passed directly to pip.

This is currently not enabled in the default tox run, however it is
possible to enable it as a default by adding it to 'envlist' in tox.ini

This also removes requirements.txt from tox.ini deps
This is redundant, per lifeless email:
http://lists.openstack.org/pipermail/openstack-dev/2015-July/069663.html

Change-Id: I79c0ceb46fc980840a8baf5fa4a303bb450bfbec
2016-09-21 10:09:47 +00:00
Jenkins
f2ec9fc99a Merge "'tox -e py27' failed" 2016-09-21 09:20:10 +00:00
OpenStack Proposal Bot
0d6166760a Updated from global requirements
Change-Id: I17b916ccbb31ca6bf72579fc10327e2e91ec3cf2
2016-09-21 07:35:28 +00:00
licanwei
d8ae88dd40 'tox -e py27' failed
cfg.CONF.debug should be set False as default,
If it's True, some unittests can't pass.

Change-Id: Ib098250af3aec48aa9d9152e20c80460f3bd641e
Closes-Bug: #1625560
2016-09-21 15:28:00 +08:00
Ha Van Tu
9eeaa07188 Fix typo in docstring from "interprete" to "interpret"
Change-Id: I931aa71dcf208a33ad8f48037b1296a4339e9b76
2016-09-21 12:16:36 +07:00
zhangyanxian
88b04dba2c Fix a typo in watcher.po
TrivialFix

Change-Id: I71a5338df14c5f5b65bed93fc26dabde447c596c
2016-09-21 03:19:35 +00:00
Jenkins
adf65f9f42 Merge "Deactivate dashboard plugin until fixed" 2016-09-20 16:18:06 +00:00
Vincent Françoise
1fc59cca9f Deactivate dashboard plugin until fixed
I deactivated the watcher-dashboard plugin in the docs since it
doesn't at the moment. Will be reactivated once it gets fixed
(see https://bugs.launchpad.net/devstack/+bug/1540328).

Change-Id: I65de8ca4a08cdb294d0e48eac52927eed13ec66c
2016-09-20 17:23:27 +02:00
Jenkins
1887ae402f Merge "Fix a typo in basic_consolidation.py" 2016-09-20 10:11:56 +00:00
licanwei
7714f48520 remove redundant word
root.description = ("Watcher is an OpenStack project which aims to"
                    "to improve physical resources usage through"
Here more one 'to'

Change-Id: I3dac6cb15af43583a1360b7f2f14d4e2c9c26cf9
2016-09-20 15:54:55 +08:00
licanwei
f741434209 Fix a typo in basic_consolidation.py
LOG.info(_LI("Initializing Sercon Consolidation"))
here 'Sercon' should be 'Server'

Change-Id: I3dc341a49066a7280bebb75471c8b433c7d0c1e7
2016-09-20 14:25:36 +08:00
Jenkins
3a3ce0268b Merge "Update Watcher description" 2016-09-19 13:33:33 +00:00
Jenkins
e647c8e01d Merge "Update reno for stable/newton" 2016-09-19 13:11:54 +00:00
Antoine Cabot
8cf233ab03 Update Watcher description
This change-set update Watcher description
as it is used in the ML to announce each
new release.

Change-Id: I6318107c3e3322a3ef734e90c9e3e0176967ceaf
2016-09-19 15:00:00 +02:00
Vincent Françoise
56a9dd0f08 Test code tidy up
Removed some comments and replace some hardocded values with the
correct variable.

Change-Id: Ica897f2de25c9de04ec2d0f94e7a13e84ee97dbb
2016-09-19 10:50:04 +02:00
Thierry Carrez
f79bed060c Update reno for stable/newton
Change-Id: Ia64ef5a4c1cd135b1bf4bbc8486270a0ff067122
2016-09-16 14:51:10 +00:00
Jenkins
e32df3c5eb Merge "Updated from global requirements" 2016-09-16 13:35:32 +00:00
Vincent Françoise
55537d254e Fixed issue on compute nodes iteration
In this changeset, I fixed the issue with the basic server
consolidation strategy to now loop over all compute nodes
as expected instead of stopping after the first one.

Change-Id: If594f0df41e39dfb0ef8f0fce41822018490c4ec
Closes-bug: #1548874
2016-09-16 14:55:51 +02:00
Vincent Françoise
e621f5ddc6 Refactored Tests to load scenarios from file
In this changeset, I simplified the logic that is used to create
cluster data model scenarios.

Change-Id: Ia6e138d9897190d3207a70485dc62ccc34087686
2016-09-16 14:51:42 +02:00
Jenkins
fc36a7a698 Merge "Remove group_by statement in metric queries" 2016-09-16 08:23:51 +00:00
OpenStack Proposal Bot
b2fe413a53 Updated from global requirements
Change-Id: I1dbcf1796b49de27fa8fb6711e4610fb934ba000
2016-09-15 20:27:53 +00:00
David TARDIVEL
b6ab86c45a Remove group_by statement in metric queries
ceilosca seems to not correctly handle group_by statement.
I remove it, because we don't need it for now.

Change-Id: Ie18551ba5a6bd155f9f4ae9c29c25b379affe019
Closes-Bug: #1623983
2016-09-15 17:16:38 +02:00
Jenkins
eeb2788355 Merge "Add rally-jobs folder to get rally support" 2016-09-15 15:15:52 +00:00
Alexander Chadin
af7871831a Add rally-jobs folder to get rally support
This patch set adds rally-jobs folder with watcher.yaml scenario
to get rally support for Watcher project

Change-Id: Icb8eace045d86a9b78b543a8a49fe747f4b00772
2016-09-15 12:54:10 +00:00
Vincent Françoise
fbd9411fd9 Log CDM structure before+after executing strategy
In this changeset, I added debug logs to dump the cluster data model
copy structure (as XML) before and after the execution of the strategy.

By doing so, we can see the cluster data model structure that is
expected after the execution of the corresponding action plan.

Change-Id: I81c23e148a78d9b176154f7620087a322a5bce28
2016-09-15 12:25:44 +00:00
Jenkins
0a0f482f2d Merge "Fixed Tempest test due to notification issues" 2016-09-15 09:55:33 +00:00
Jenkins
0873c26b17 Merge "Use memory mode for sqlite in db test" 2016-09-14 13:39:51 +00:00
Jenkins
af99b3f4eb Merge "Use parameters instead of config for workload stabilization" 2016-09-14 13:33:34 +00:00
Jenkins
4b20e991a1 Merge "Added tests on API hooks and related context" 2016-09-14 12:41:09 +00:00
Jenkins
e907cec90a Merge "When action plan is empty, its state is incorrect" 2016-09-14 12:39:39 +00:00
Jenkins
9f814e6c15 Merge "The default value of 'is_admin_project'" 2016-09-14 12:38:00 +00:00
Jenkins
5ac51efa69 Merge "Implemented GMR plugin to show CDM structures" 2016-09-14 10:09:55 +00:00
Jenkins
0baec1cfc2 Merge "Fixed indentation" 2016-09-14 09:29:51 +00:00
Vincent Françoise
72e6564549 Fixed Tempest test due to notification issues
Change-Id: I33a0764060600b8e3d6bec757669490b9003b345
2016-09-09 16:03:12 +02:00
ChangBo Guo(gcb)
23092b6f84 Use memory mode for sqlite in db test
Config option sqlite_db is deprecated in
0a1bae9859079fb21a03716be947c5f1da6db0a2, and deprecate argumentsqlite_db in method set_defaults in
https://review.openstack.org/#/c/350945/, should use config option
connection instead. For watcher, we test database with sqlite in memory
mode [1] as below:

cfg.CONF.set_override("connection", "sqlite://",
                      group="database", enforce_type=True)

and don't use config option sqlite_db, so remove unused code.

[1]http://docs.sqlalchemy.org/en/rel_1_0/core/engines.html#sqlite

Change-Id: I9b1f995e1b7004bcfe6c5a854c2f83b24e5bfb56
2016-09-09 19:51:15 +08:00
Vincent Françoise
0b276fb602 Added tests on API hooks and related context
In this changeset, I raised the overall test coverage on the Watcher
API hooks.

Change-Id: I718030fdd23e83bf50d22b00828664adf66fc59d
2016-09-08 12:18:07 +02:00
licanwei
a684e70b61 When action plan is empty, its state is incorrect
When the action plan is empty,its state is still 'RECOMMENDED'.
I think it's should be 'SUCCEED'.
Closes-Bug: #1619155

Change-Id: Icd10707c7892089999f8b37775ca62bde47db0c4
2016-09-08 13:37:39 +08:00
Jenkins
414685ab53 Merge "Add documentation for Scoring Module" 2016-09-07 14:20:32 +00:00
Alexander Chadin
2d8650f87a Use parameters instead of config for workload stabilization
This patch set allows to use audit parameters for
workload-stabilization strategy and makes some little
refactoring.

Closes-Bug: #1620604
Change-Id: I60e34611d4dd001beed31666fd11d2ab11c1723c
2016-09-07 17:15:07 +03:00
Tomasz Kaczynski
dd924dd9d5 Add documentation for Scoring Module
This change is updating the glossary with Scoring Module terms
and adding an information page about implementing scoring engine
plugin.

Partially-Implements: blueprint scoring-module
Change-Id: I411370dcc003ed837d8ce67659ecbfef3548ee11
2016-09-07 08:13:36 +00:00
Jenkins
dd5b5428db Merge "Fix incorrect strings and formatting" 2016-09-06 10:58:16 +00:00
Vincent Françoise
74989fe94e Implemented GMR plugin to show CDM structures
In this changeset, I implemented a small GMR plugin that converts
the cluster data model structure into an XML structure.

Change-Id: I75548952635a0aa3c7dbd6d068831b5765a5db1a
Closes-Bug: #1620551
2016-09-06 12:15:51 +02:00
Michelle Mandel
3b673fe9bd Fix incorrect strings and formatting
There were a few typos and some lines of code that weren't formatted
properly. Now, the typos are fixed and the misformatted code is
corrected.

Change-Id: I6009e44f65b9be1ae9edc806618342c334b2fa92
2016-09-02 14:46:05 -04:00
Bin Zhou
c1cbd9ebf4 Modify use of assertTrue(A in B)
Developers should use assertIn(A, B) instead of assertTrue(A in B ).

TrivialFix

Change-Id: Ie169e731c800b5d77fd231f09ac7f92090287ef3
2016-09-02 12:43:56 +08:00
Gábor Antal
add49f3fcb Fixed indentation
In some places, indentation was wrong.
In this patchset, they are fixed.

Change-Id: Ic66105d53b76cf53fbb4bc7bc19329b83b89687e
2016-09-01 19:00:25 +02:00
licanwei
1f4a46ea5d The default value of 'is_admin_project'
The default value of 'is_admin_project' should be 'True'
As in the file '/oslo_context/context.py':
    def __init__(self,...
                 is_admin_project=True)

Change-Id: Id5e3f7347819deff27c6423679f9964fbb35f047
2016-08-31 15:30:31 +08:00
Jenkins
8a38c4f479 Merge "Add release notes for Newton blueprints" 2016-08-30 07:36:57 +00:00
Jenkins
107cc76cdb Merge "TrivialFix: Remove cfg import unused" 2016-08-29 14:44:40 +00:00
Alexandr Stavitskiy
6e8dc5297e Merge scoring base files
Merge scoring_engine.py and scoring_container.py to base.py

Change-Id: I5cada2c9f7832827c1bccfdea1b0a2138b18bfc9
Closes-Bug: #1617376
2016-08-29 14:59:47 +03:00
Antoine Cabot
7cce4b9ed4 Add release notes for Newton blueprints
Change-Id: Id643dae85b1df86796d27fa885aa7c7303d4f4d8
2016-08-29 12:56:02 +02:00
Cao Xuan Hoang
deb5cb3fc2 TrivialFix: Remove cfg import unused
This patch removes cfg import unused in
watcher/api/controllers/v1/goal.py
watcher/api/controllers/v1/strategy.py
watcher/decision_engine/cluster/history/ceilometer.py
watcher/decision_engine/model/collector/manager.py
watcher/decision_engine/strategy/selection/default.py
watcher/tests/common/test_ceilometer_helper.py
watcher/tests/decision_engine/fake_strategies.py
watcher/tests/decision_engine/strategy/selector/test_strategy_selector.py

Change-Id: I0f30a056c3efa49faed857b6d1001a2367d384ac
2016-08-29 15:01:28 +07:00
Jenkins
3ed44383ab Merge "TrivialFix: Remove logging import unused" 2016-08-29 07:48:35 +00:00
Cao Xuan Hoang
720884cd55 TrivialFix: Remove logging import unused
This patch removes logging import unused in
watcher/applier/manager.py
watcher/applier/rpcapi.py
watcher/decision_engine/goal/base.py
watcher/decision_engine/model/notification/base.py
watcher/decision_engine/model/notification/filtering.py

Change-Id: I0b967e4931223b3b7e9459fb1483ed8185a1a7a0
2016-08-29 12:46:02 +07:00
gecong1973
249cd11533 Remove unused LOG
delete unused LOG in some files

Change-Id: I38f2a91d2e6b24b14e1d46fd8e9a5f87ea2f3171
2016-08-29 10:03:33 +08:00
Jenkins
f42106ca34 Merge "Add unit tests for continuous.py" 2016-08-26 17:44:30 +00:00
Jenkins
359debb6b0 Merge "Update configuration section for notifications" 2016-08-26 17:22:29 +00:00
Jenkins
dbcab41fae Merge "Doc on how to add notification endpoints" 2016-08-26 17:22:22 +00:00
Jenkins
28ff52f8ba Merge "Notification and CDM partial update" 2016-08-26 17:01:23 +00:00
Jenkins
781eb64c6a Merge "Added start/end date params on ceilometer queries" 2016-08-26 16:29:33 +00:00
Jenkins
45a0bda1ae Merge "Fix loading of plugin configuration parameters" 2016-08-26 16:26:17 +00:00
Jenkins
190d5ae899 Merge "Remove unreachable line" 2016-08-26 16:16:44 +00:00
David TARDIVEL
e4ba59e130 Update configuration section for notifications
Watcher consumes now notications sent by Nova services.
We have to configure Nova to publish its notifications into
the dedicated Watcher notification queue.

Change-Id: I29f2fa12dfe3a7ce0b014778109a08bbe78b4679
Partially-Implements: blueprint cluster-model-objects-wrapper
2016-08-26 15:57:54 +00:00
Vincent Françoise
f238167edc Doc on how to add notification endpoints
In this changeset, I updated the CDMC plugin documentation to explain
how to implement and register new notification endpoints.

Change-Id: Ib8c014e82051647edef5c1272f63429f76673227
Partially-Implements: blueprint cluster-model-objects-wrapper
2016-08-26 17:46:50 +02:00
Vincent Françoise
77b7fae41e Notification and CDM partial update
In this changeset, I implemented the notification handling (Rx only)
system for consuming incoming notifications, more especially the Nova
ones. The notifications handlers also contain the logic which
incrementally updates the Compute model.

Change-Id: Ia036a5a2be6caa64b7f180de38821b57c624300c
Partially-implements: blueprint cluster-model-objects-wrapper
2016-08-26 17:46:48 +02:00
Jenkins
8c23c08776 Merge "Check unspecified parameters create audit" 2016-08-26 14:53:17 +00:00
Viacheslav Samarin
103f541abd Remove unreachable line
This patch set removes unreachable line from nova_helper.py

Change-Id: I0befe271cc244b73fb9f4d79cc1d04b951b67135
Closes-Bug: #1617354
2016-08-26 17:43:59 +03:00
Jenkins
5fe6281e5c Merge "Correct watcher reraising of exception" 2016-08-26 14:16:45 +00:00
Vincent Françoise
c61793811e Added start/end date params on ceilometer queries
In this changeset, I added the start_time and end_time params
to the Ceilometer helper which can drastically reduce the execution
time of the queries.

Change-Id: I39cb3eef584acfca1b50ff6ec1b65f38750802d2
2016-08-26 14:16:19 +00:00
gengchc2
ecea228c4c Correct watcher reraising of exception
When an exception was caught and rethrown, it should call 'raise'
without any arguments because it shows the place where
an exception occured initially instead of place where
the exception re-raised

Change-Id: I662583cd3cda2424d5a510cae7e815c97a51c2fe
2016-08-26 12:52:13 +00:00
jinquanni
1fafcc5ef1 Check unspecified parameters create audit
Currently, create audit with unspecified parameters will success.
This is not reasonable, we shoud return a FAILED status to
notify the admin user.

Change-Id: Ifbcb3b8d9e736607b05b1eb408ec0f41bdf58a2f
Closes-Bug: #1599879
2016-08-26 19:18:20 +08:00
David TARDIVEL
32c13d00fe Fix loading of plugin configuration parameters
When the load a plugin, we need to reload once the watcher
configuration data, in order to include the plugin parameters in
cfg.CONF data dict. To reload the conf, we just call self.conf().
But every time we call this method, cfg.CONF is cleaned, and we
lost previously loaded parameters. This generated the exception
RequiredOptError and the plugin was not correctly loaded.

To fix it, we have just to add the watcher configuration
filename as argument of self.conf().

Change-Id: Ic2384b68f6d604640127fe06893d0f808aee34b7
Closes-Bug: #1617240
2016-08-26 12:08:45 +02:00
Tomasz Kaczynski
a1cb142009 Add Scoring Module implementation
This change is adding the main logic for the scoring module,
defines entry points for the scoring engine plugins and provides
a watcher-sync tool to enable Watcher database synchronization
without needing to restart any Watcher service.

Partially-Implements: blueprint scoring-module
Change-Id: If10daae969ec27a7008af5173359992e957dcd5e
2016-08-26 07:13:39 +00:00
Jenkins
ab10201c72 Merge "Added strategy ID + Action Plan syncing" 2016-08-25 21:08:08 +00:00
Jenkins
42b45a5949 Merge "Fixed flaky tempest test" 2016-08-25 15:50:38 +00:00
licanwei
da67b246a5 Add unit tests for continuous.py
Add unit tests about functions 'execute_audit'
and 'is_audit_inactive'

Change-Id: If9eb4d95166a486a59cc1535106944243bb7eb30
Closes-Bug: #1616759
2016-08-25 16:52:58 +08:00
OpenStack Proposal Bot
6d41c23e50 Updated from global requirements
Change-Id: I4501b494acc27f9471ea0ba1cf0151242ce17002
2016-08-25 05:06:56 +00:00
Vincent Françoise
7b228348a0 Fixed flaky tempest test
Fixed the flaky test_delete_audit test which was failing if the delete
query was sent before the audit reaches an 'idle' state.

Change-Id: I244643b1f7c9b31baa5c25753e62dd3da0a53544
2016-08-24 14:45:51 +02:00
Jenkins
eb421709d9 Merge "Updated from global requirements" 2016-08-24 11:55:02 +00:00
Andreas Jaeger
e741728eb8 Remove pot files
We do not store pot files anymore in repositories,
instead they are published at
http://tarballs.openstack.org/translation-source/watcher/master/ after
each commit and thus always accurate.

Remove the outdated and obsolete file.

Change-Id: I24f18c0a62f2c5339479d07904fb2ce0a888c696
2016-08-24 08:40:53 +02:00
OpenStack Proposal Bot
35201c8358 Updated from global requirements
Change-Id: I430ed2e1a4e2c29e35f57c6362589eb0ed36465c
2016-08-24 01:40:02 +00:00
Vincent Françoise
6be758bc5a Added strategy ID + Action Plan syncing
In this changeset, I implemented the logic which cancels
any audit or action plan whose goal has been re-synced
(upon restarting the Decision Engine).

Partially Implements: blueprint efficacy-indicator

Change-Id: I95d2739eb552d4a7a02c822b11844591008f648e
2016-08-22 10:08:05 +02:00
Jenkins
5f205d5602 Merge "Fixes to get cluster data model" 2016-08-22 07:51:46 +00:00
Prashanth Hari
9450a7079b Fixes to get cluster data model
Due to the recent code refactor in the cluster data model
compute model is failing to 'get_latest_cluster_data_model'
attribute

Change-Id: Iba848db6d03cf1b682c4000ca48cf846b0ffa79b
Closes-Bug: #1614296
2016-08-19 15:44:09 -04:00
OpenStack Proposal Bot
64f45add5f Updated from global requirements
Change-Id: I1651d322933e085773210920de257572eb142089
2016-08-19 09:12:46 +00:00
Jenkins
3a804ae045 Merge "Fix double self._goal definition" 2016-08-18 17:00:13 +00:00
Jenkins
638fd557dc Merge "Scheduler of decision_engine fix" 2016-08-18 15:44:05 +00:00
Alexandr Stavitskiy
4e3593a71d Fix double self._goal definition
This patch set removes second self._goal definition.

Change-Id: I343b82e1584ab30129e6f15cc9c15cee07250497
Closes-Bug: #1614568
2016-08-18 17:53:09 +03:00
Viacheslav Samarin
01164b0790 Scheduler of decision_engine fix
This patch set renames 'OS-EXT-STS:instance_state' to 'OS-EXT-STS:vm_state'
for correct working of decision_engine scheduler.

Change-Id: I20805a079a991d5f3b8565f52d5f7280c2389bee
Closes-Bug: #1614511
2016-08-18 16:49:20 +03:00
OpenStack Proposal Bot
9933955c7d Updated from global requirements
Change-Id: Id07d8af7e1c717d52005e73bf43baa67f60e2242
2016-08-18 05:58:34 +00:00
Jenkins
efdf6c93fc Merge "Modify libvirt_opts="-d -l" to libvirtd_opts="-d -l"" 2016-08-17 06:28:26 +00:00
Nguyen Hung Phuong
17d2d75abb Clean imports in code
In some part in the code we import objects.
In the Openstack style guidelines they recommand to import
only modules. We need to fix that.

Change-Id: I268c5045f00d25b4dfbf77c1f599c7baca8373ed
Partial-Bug:1543101
2016-08-15 13:43:28 +07:00
zte-hanrong
2e55f4ebee Modify libvirt_opts="-d -l" to libvirtd_opts="-d -l"
Change-Id: Iebb5ab722e416e83abfe48e7b66633645c63f94b
2016-08-13 16:19:54 +08:00
Jenkins
196a7a5457 Merge "Add unit tests for nova_helper.py" 2016-08-09 11:33:17 +00:00
Jenkins
1f72a35896 Merge "Updated from global requirements" 2016-08-09 11:31:04 +00:00
Joe Cropper
ea01031268 Rename (pre/post)condition to (pre/post)_condition
This patch updates the applier's abstract methods to be consistent
with other abstract methods of similar nature.

Also included are a few other miscellaneous changes.

Change-Id: Ia1527c00332011412aba2ab326ec986f1e773001
Closes-bug: 1606634
2016-08-08 08:25:41 -05:00
licanwei
6144551809 Add unit tests for nova_helper.py
The nova helper does not have a sufficient code coverage.
This commit raises its coverage from 39% to 89%.
And unit tests find two bugs.

Closes-Bug: #1607198
Change-Id: Iebb693cd09e512ce44702eddca8ead0c7310b263
Closes-Bug: #1599849
2016-08-08 19:39:58 +08:00
OpenStack Proposal Bot
1b2672a49b Updated from global requirements
Change-Id: Ia64e68758d3335e3ba4ca3c15f00ca6cbb25daa3
2016-08-08 10:49:38 +00:00
Jenkins
27b3c5254d Merge "Removed unused function in uniform airflow" 2016-08-05 01:43:19 +00:00
Jenkins
d69efcbd0f Merge "Updated from global requirements" 2016-08-04 16:02:38 +00:00
Vincent Françoise
31de0e319f Removed unused function in uniform airflow
In this changeset, I removed 2 unused methods.

Change-Id: I2e85ed63739f9bb436d110b54fe2b9ef10962205
2016-08-04 14:55:23 +02:00
zhangyanxian
8145906798 Update the home-page info with the developer documentation
Since there are so many components in openstack,
by describing the URL info in the configuration file,
it is more convenient to find the developer documentation
than from the unified portal

Change-Id: Id6bc554db8bb0cd71851773b9cea71aada4eb9e2
2016-08-04 06:11:42 +00:00
OpenStack Proposal Bot
9d2d2183f5 Updated from global requirements
Change-Id: I4ac7f94a726eb6a1dc1ff8f930f517df0731779d
2016-08-04 02:43:22 +00:00
Vincent Françoise
31c37342cd Refactored the compute model and its elements
In this changeset, I refactored the whole Watcher codebase to
adopt a naming convention about the various elements of the
Compute model so that it reflects the same naming convention
adopted by Nova.

Change-Id: I28adba5e1f27175f025330417b072686134d5f51
Partially-Implements: blueprint cluster-model-objects-wrapper
2016-08-03 12:10:43 +02:00
Jenkins
dbde1afea0 Merge "use parameters to set the threshold" 2016-08-03 08:28:16 +00:00
Jenkins
739b667cbc Merge "Merged metrics_engine package into decision_engine" 2016-08-02 16:34:48 +00:00
Jenkins
671c691189 Merge "Updated DE architecture doc + 'period' param" 2016-08-02 16:34:11 +00:00
Jenkins
32be5de2f9 Merge "Added DE Background Scheduler w/ model sync jobs" 2016-08-02 16:33:51 +00:00
Jenkins
cf01dad222 Merge "Cluster data model collector plugin documentation" 2016-08-02 16:28:56 +00:00
Jenkins
027ce5916c Merge "Loadable Cluster Data Model Collectors" 2016-08-02 16:28:51 +00:00
Jenkins
39227f6e86 Merge "Use more specific asserts" 2016-08-02 14:08:14 +00:00
Gábor Antal
cc2e805780 Use more specific asserts
Many places, there are more specific asserts which can be used.
I replaced the generic assert with more specific ones, where
it was possible.

This change enhances readibility, and on fail, more useful
message is displayed

Change-Id: I86a6baeae2cd36610a2be10ae5085555246c368a
2016-08-02 14:42:29 +02:00
Vincent Françoise
0a6841f510 Merged metrics_engine package into decision_engine
In this changeset, I merged the metrics_engine package into
the decision_engine one alongside the required changes to make
the tests pass.

Change-Id: Iac1cd266a854212bf4fa8b21c744b076c3b834a8
Partially-Implements: blueprint cluster-model-objects-wrapper
2016-08-02 12:07:35 +02:00
Vincent Françoise
4f8591cb02 Updated DE architecture doc + 'period' param
In this changeset, I updated the architecture documentation
about the Decision Engine by adding a new sequence diagram
outlining the CDM synchronization workflow.
I also explained the default 'period' parameter used in the
CDMC plugin.

Change-Id: I09790281ba9117e302ab8e66a887667929c6c261
Partially-Implements: blueprint cluster-model-objects-wrapper
2016-08-02 12:07:35 +02:00
Vincent Françoise
06c6c4691b Added DE Background Scheduler w/ model sync jobs
In this changeset, I implemented a background scheduler service
for Watcher and more particularly for the Decision Engine where
I made it create 2 types of job per cluster data model collector
plugin:

- An initial job that is asynchronously executed upon starting the
  Decision Engine
- A periodical job that gets triggered every configurable interval
  of time

Change-Id: I3f5442f81933a19565217b894bd86c186e339762
Partially-Implements: bluprint cluster-model-objects-wrapper
2016-08-02 12:07:35 +02:00
Vincent Françoise
b94677c3ef Cluster data model collector plugin documentation
In this changeset, I wrote down the documentation on how to implement
a cluster data model collector plugin for Watcher.

This documentation corresponds to part 1 of the associated
specification.

Change-Id: Iac72b933df95252163033cd559d13348075a9b16
Partially-Implements: blueprint cluster-model-objects-wrapper
2016-08-02 12:07:35 +02:00
Vincent Françoise
5a2a94fbec Loadable Cluster Data Model Collectors
In this changeset, I made BaseClusterDataModelCollector instances
pluggable. This corresponds to "part 1" of the work items detailed
in the specifications.

Change-Id: Iab1c7e264add9e2cbbbb767e3fd6e99a0c22c691
Partially-Implements: blueprint cluster-model-objects-wrapper
2016-08-02 12:07:35 +02:00
Jenkins
553c5a6c4b Merge "Add scoring engines to database and API layers" 2016-08-02 08:09:39 +00:00
Jenkins
5ffb7df20c Merge "Implement goal_id, strategy_id and host_aggregate into Audit api" 2016-08-02 07:59:46 +00:00
OpenStack Proposal Bot
61e581f45e Updated from global requirements
Change-Id: I5d8a4f1e4c3b72e248181ba4da5bd0e6f17c164d
2016-08-01 18:49:15 +00:00
Tomasz Kaczynski
26d84e353e Add scoring engines to database and API layers
A Scoring Module needs to expose a list of available
scoring engines through API and Watcher CLI. This list
is stored in database and synchronized by Decision Engine.

Partially-Implements: blueprint scoring-module
Change-Id: I32168adeaf34fd12a731204c5b58fe68434ad087
APIImpact
2016-08-01 12:40:33 +00:00
Jenkins
b2656b92c4 Merge "Add installation from Debian packages section" 2016-07-29 01:55:50 +00:00
Michael Gugino
52ffc2c8e2 Implement goal_id, strategy_id and host_aggregate into Audit api
Modifying the api controller for audit objects to allow
creation of audit objects by specifying either an
audit_template uuid/id and/or a goal_id.

strategy_id is optional.

Partially Implements: blueprint persistent-audit-parameters
Change-Id: I7b3eae4d0752a11208f5f92ee13ab1018d8521ad
2016-07-28 20:12:52 -04:00
junjie huang
5dee934565 use parameters to set the threshold
use parameters to set the threshold for strategies
of Uniform Airflow,Workload balance.

Change-Id: I5a547929eb1e2413468e9a5de16d3fd42cabadf9
Close-bug: #1600707
2016-07-28 11:28:41 +00:00
OpenStack Proposal Bot
0769e53f93 Updated from global requirements
Change-Id: I60b1bc77b3819d8fadddbd13a55b00da8e206b2f
2016-07-28 06:09:16 +00:00
Jenkins
8db3427665 Merge "Add hacking checks to watcher" 2016-07-27 09:10:06 +00:00
Jenkins
35dfa40b08 Merge "Add Python 3.5 classifier and venv" 2016-07-27 09:09:55 +00:00
Jenkins
a98636cd09 Merge "Fixed Basic optim tempest test" 2016-07-26 09:45:18 +00:00
Vincent Françoise
107bd0be54 Fixed Basic optim tempest test
In this changeset, I made some fixes in order to make the
multinode test pass on the gate.

Change-Id: I2433748a78c87b15893ea69964561955b478eebd
2016-07-26 10:43:07 +02:00
Jenkins
95917bc147 Merge "Fix 2 occurrences of typo: "occured" --> "occurred"" 2016-07-26 07:23:23 +00:00
Jenkins
cc1f66cd6a Merge "Update docs links to docs.openstack.org" 2016-07-26 06:29:41 +00:00
Ralf Rantzau
926b790747 Fix 2 occurrences of typo: "occured" --> "occurred"
Change-Id: Ie25223e8aebdc05bc0f19b9df4805dfb942f1818
2016-07-25 14:21:21 -07:00
Drew Thorstensen
7d704dbeec Add hacking checks to watcher
The hacking checks enforce during the pep8 run functional validations of
the code to ensure deeper filters and code consistency.  This change set
adds the hacking checks to the wathcer project.  These checks were
seeded from the neutron project, which had a good set of base defaults.

This change set also updates the watcher project to be compliant with
these new hacking checks.

Change-Id: I6f4566d384a7400bddf228aa127a53e6ecc82c2e
2016-07-25 07:52:45 -04:00
Tin Lam
5c08095417 Update docs links to docs.openstack.org
Changed reference from https://factory.b-com.com to
http://docs.openstack.org.

Change-Id: Ifb8b09ff9df5c67e49b594b7373f11082e00029a
Partial-Bug: #1595180
2016-07-21 13:37:16 -05:00
Jenkins
65d3a4d75e Merge "Updated from global requirements" 2016-07-21 13:29:16 +00:00
Jenkins
6727d53072 Merge "Fix dict.keys() PY3 compatible" 2016-07-21 13:02:16 +00:00
Swapnil Kulkarni (coolsvap)
b579a41f30 Remove discover from test-requirements
It's only needed for python < 2.7 which is not supported

Change-Id: Ib3f24755d50ef9466e5bb35c10ea57ac28ac7a34
2016-07-21 07:47:17 +00:00
OpenStack Proposal Bot
051810dfa2 Updated from global requirements
Change-Id: Ie246370342759d9e3935b7a6e802c94e33ad3d6a
2016-07-21 04:12:17 +00:00
Jenkins
8ab80894c3 Merge "Fix typos and messages in strategies" 2016-07-20 23:58:26 +00:00
Joe Cropper
6730202151 Fix typos and messages in strategies
This patch fixes various typos and other nits in the strategies.  It
also updates some of the log messages to be a little more operator
friendly.

Change-Id: Ic9268c6d7376dad215a1a40798485b1d836ba7ae
Closes-Bug: #1604248
2016-07-20 14:19:45 -07:00
Jenkins
a6d0eaa4c4 Merge "Update executor to eventlet" 2016-07-19 19:41:22 +00:00
Jenkins
2e04ba6b64 Merge "There are some spelling errors in the code." 2016-07-19 19:41:13 +00:00
Muzammil Mueen
fd7c41fba2 Remove unused columns parameters in watcher/db/api
In watcher/db/api.py, some abstract methods are specifying a 'columns'
parameter that is actually ignored in db/sqlalchemy/api.py. Since we
do not need this parameter, realignment was done for the signatures
of these methods, by removing the 'column' parameter (and its
docstring) from every single one of the following methods.

get_audit_template_list
get_audit_list
get_action_list
get_action_plan_list

Closes-Bug: #1597641
Change-Id: If706e24d5714f0139fd135bdc41d17d0e431e302
2016-07-19 09:51:41 -07:00
licanwei
aef1eba5df test_context_hook_before_method failed
gate-watcher-python27 FAILURE
The reason is that oslo_context.context.__init__()
added parameter 'domain_name'.
There are some mismatching in file '/watcher/common/context.py'

Change-Id: If0be05943e7c89788d6ccba3385474ccb036e6f5
Closes-Bug: #1604214
2016-07-19 10:58:14 +08:00
weiweigu
cd60336e20 Fix dict.keys() PY3 compatible
The dict.keys()[0] will raise a TypeError in PY3,
as dict.keys() doesn't return a list any more in PY3
but a view of list.

Change-Id: If15a153c9db9b654e761f8ad50d5d66a427efa4e
Closes-Bug: #1583419
2016-07-14 13:47:29 +08:00
Jenkins
8635beb045 Merge "Fix unittest in test_api.py" 2016-07-13 13:21:27 +00:00
Jenkins
ff1af61c1b Merge "Update unitaty tests to verify strategy and goal name" 2016-07-13 12:54:45 +00:00
Jenkins
00adcb84f6 Merge "Optimize local.conf.controller file to enable watche-dashboard" 2016-07-13 12:45:30 +00:00
zhangyanxian
e7a1ba7e74 There are some spelling errors in the code.
Change-Id: Ifb88a13783fc12258489abb4caabca1b1038a77d
2016-07-13 02:36:47 +00:00
Yatin Kumbhare
1b0801a0c3 Add Python 3.5 classifier and venv
Now that there is a passing gate job, we can claim support for
Python 3.5 in the classifier. This patch also adds the convenience
py35 venv.

Change-Id: Idf6cd632bcb6f4f61dba65fedc9309d0184f46b7
2016-07-12 21:23:43 +05:30
David TARDIVEL
a68eb0d619 Update unitaty tests to verify strategy and goal name
strategy and goal name must be synched with entry point names.

Change-Id: I776ed98f5c13d176fdb0b8677d609fcb1ec9a235
Closes-Bug: #1602262
2016-07-12 16:54:38 +02:00
David TARDIVEL
517f1d083e Bad goal and strategy name for Airflow Optimization
The goal name 'airflow optimization' must be synched with the
entry point name.
The strategy name 'uniform airflow' must be synched with the
entry point name.

Partial-Bug: #1602262

Change-Id: Ibc6f0a7c5047e57549910818200c323b878152b0
2016-07-12 15:45:59 +02:00
licanwei
76a61e234a Fix unittest in test_api.py
tox -e py27 fails with this error:
socket.error: [Error 98] Address already in use

Change-Id: I1cf4a000fb82228bed6a7da61feed48ab679b891
Closes-Bug: #1599556
2016-07-12 17:02:43 +08:00
Jenkins
f4b631ebb3 Merge "Add new documentation section for Watcher policies rules" 2016-07-12 08:14:33 +00:00
Jenkins
e78610e7d1 Merge "Make default Planner generic to handle new action" 2016-07-12 07:35:21 +00:00
Jenkins
405cde2ff9 Merge "Uniform Airflow migration strategy implementation" 2016-07-11 07:56:26 +00:00
Jenkins
b25ecde0db Merge "Add continuously optimization" 2016-07-08 14:07:51 +00:00
Jenkins
e6b4befbf4 Merge "Fix watcher doc build error" 2016-07-08 14:07:39 +00:00
zte-hanrong
dcf52077a4 Optimize local.conf.controller file to enable watche-dashboard
Change-Id: I51cfca4d55453710685624d5cf16a92271947b6a
2016-07-08 10:06:10 +08:00
Alexander Chadin
1de00086f5 Add continuously optimization
This patch set adds implementation for CONTINUOUS type
of audit.

Change-Id: I5f4ec97b2082c8a6b3ccebe36b2a343fa4a67d19
Implements: blueprint continuously-optimization
2016-07-07 19:17:17 +03:00
Jenkins
518b4c82f1 Merge "Documentation for strategy parameters" 2016-07-07 15:10:02 +00:00
Jenkins
4423fdd231 Merge "Add Desktop Service Store to .gitignore file" 2016-07-07 15:09:53 +00:00
Jenkins
b1c6ea71a4 Merge "Fix field type to audit_type" 2016-07-07 08:57:44 +00:00
Alexander Chadin
533a4c7a34 Add Desktop Service Store to .gitignore file
This patch set adds Desktop Service Store files to .gitignore to
ignore them.

Change-Id: Iff3221eea6b0b3f51dd32097f762252b4a4ffa2d
2016-07-07 11:05:56 +03:00
Jenkins
d61c4c12d1 Merge "Fix failing Tempest tests" 2016-07-07 06:58:13 +00:00
Edwin Zhai
1d3891e1e4 Documentation for strategy parameters
Add docs of how to define and input parameters of strategy.

Change-Id: I918305b89721d141b7f37630459e6cf5999f4211
Partially-Implements: optimization-threshold
2016-07-07 00:03:43 +00:00
OpenStack Proposal Bot
f13d6dd805 Updated from global requirements
Change-Id: Ie17905661161bb34b9da611201e447117cb04544
2016-07-06 16:42:29 +00:00
Jenkins
81bdc51e21 Merge "Add policies for API access control to watcher project." 2016-07-06 16:17:43 +00:00
David TARDIVEL
ff4375337e Add installation from Debian packages section
Debian experimental packages are now available for Watcher.
I added a new section to help users to quickly deploy these
packages and test them.

Change-Id: Ib920b7dbf968c36941c0d30c9001bc150df543f8
2016-07-06 15:58:50 +00:00
David TARDIVEL
e7bbf1d1b9 Add new documentation section for Watcher policies rules
We can now use policies to allow or not users to invoke Watcher API
methods. I added, in the Admin guide section, a new documentation
introducing watcher policy rules.

Change-Id: Ie1f8a9e15561756f23242c6f6b0d53cdacf3505a
blueprint: watcher-policies
2016-07-06 15:42:12 +00:00
David TARDIVEL
21d1610071 Update executor to eventlet
Default 'blocking' executor handles only one message at once.
'eventlet' executor is recommended.

Change-Id: Id738d0462fbb3c7fd6c78ee2f0dd0f1e79131ca7
Closes-Bug: #1517843
2016-07-06 17:40:55 +02:00
Jenkins
e34198f35c Merge "Fix link error in base-setup.rst" 2016-07-06 14:51:17 +00:00
zte-hanrong
bc06a7d419 Add policies for API access control to watcher project.
Change-Id: Ibdbe494c636dfaeca9cf2ef8724d0dade1f19c7f
blueprint: watcher-policies
2016-07-06 17:38:44 +08:00
Edwin Zhai
1a1d9d09f4 Fix watcher doc build error
Updates the module name to reflect the right defination of efficacy
specification, and adds doc string to some class.

Change-Id: If54e65a5e98521d74d8e19a21dd900ecd37edfe5
Closes-Bug: #1599368
2016-07-06 06:06:00 +00:00
digambar
47ff9bb105 Fix field type to audit_type
There's a number of places where a field of an object is named "type",
which isn't good thing. Actually type is keyword in python, so wherever
I found type used in models/api/object/test, I have fixed it to
audit_type in the audit files

Change-Id: Iea6bd3acb0b2af2a833b3916701aad88f6064bba
Closes-Bug: #1533392
2016-07-06 06:26:15 +05:30
jinquanni
ca5b849f6b Remove duplicate unittest
There are two same unit test in test_default_planner.
We need to remove one.

TrivialFix

Change-Id: Ibeec9348779dafe4c2cec2411306e09e95728ca1
2016-07-05 14:57:47 +08:00
licanwei
2272b515bf Fix link error in base-setup.rst
line 93:An ref:'action plugin <implement_strategy_plugin>
here implement_strategy_plugin should be 'implement_action_plugin'

Change-Id: I3487578b91bd169335ccf336443e6174905728b0
Closes-Bug: #1599029
2016-07-05 14:44:01 +08:00
Vincent Françoise
f6b1b515c4 Fix failing Tempest tests
In this changeset, I fixed the 3 failing tests on the Tempest test
suite.

Change-Id: I3d31ea1c13b340a2a16b41c31198d7be4711400c
Closes-Bug: #1595534
2016-07-04 16:18:59 +02:00
Jenkins
64903ce56c Merge "Enable strategy parameters" 2016-07-04 08:57:54 +00:00
Jenkins
86cbe4bd0c Merge "Added filter operators" 2016-07-04 07:10:50 +00:00
Edwin Zhai
0b29a8394b Enable strategy parameters
Strategy provides parameters to customize algorithm behavior. End user
could query then specify parameters for their requirements.

Change-Id: Id097db5f6e79c94b57674c8e5d55b06098abf18c
Implements-bp: optimization-threshold
2016-07-01 03:01:41 +00:00
Jenkins
ec64203bee Merge "Update Docs links to docs.openstack.org" 2016-06-30 14:36:07 +00:00
Jenkins
dc01e35760 Merge "add dependency for 3rd-party plugins" 2016-06-30 07:18:13 +00:00
Palimariu Marius
117079f81e Update Docs links to docs.openstack.org
This patch updates the wrong documentation links with the new location.

Change-Id: I42b86a225ebb4b4610adf0f7f8c3286d8b24ed04
Closes-Bug: #1595180
2016-06-29 19:46:11 +00:00
licanwei
d03e1d54bd add dependency for 3rd-party plugins
In the base-setup.rst about 3rd-party plugins,
we should add the watcher dependency requirement.

Change-Id: I8f898b2e3e7e30c88f4f14f7bd3ae38b8aa3ebd3
Closes-Bug: #1594705
2016-06-29 17:44:46 +08:00
Jenkins
6bdc4cac82 Merge "Add goal_name field in strategy" 2016-06-28 15:31:00 +00:00
jinquanni
b4c5e2bb81 Make default Planner generic to handle new action
Currently we have to amend the code of the Planner
for each new added Watcher Action. This patch set will
modifying the DefaultPlanner class and  leverage the
plugins-parameters blueprint so that we can configure
weights via the configuration file.

Documentation and unittest also be update in this patch.

Co-Authored-By: Vincent Françoise <vincent.francoise@b-com.com>

Change-Id: Ib794488fcafd1e153a7d7b1f7253686136501872
blueprint: configurable-weights-default-planner
2016-06-28 07:15:36 +08:00
jinquanni
369428c313 Modify IRC weekly meeting time
modify IRC weekly meeting time in contributor.rst

Change-Id: I1e46bbf23e301559e2a92fce387c2d0f578eb814
2016-06-27 20:34:37 +08:00
junjie huang
2381a677b6 Uniform Airflow migration strategy implementation
This is one of the algorithm of Intel thermal POC.
It's based on the Airflow of hypervisors.

Change-Id: I48bbab75b20129d85b1fb15ede823474546fe399
blueprint: uniform-airflow-migration-strategy
2016-06-27 04:46:18 +00:00
OpenStack Proposal Bot
da8b24f483 Updated from global requirements
Change-Id: Ie49cb8d5fe7cee5592e6045a0145a6a7299c614b
2016-06-24 03:19:28 +00:00
Jenkins
d7a7b3ea54 Merge "Add importing modules instead of classes" 2016-06-23 15:39:08 +00:00
Tin Lam
37595e9bb7 Centralize plugin loaders in watcher/applier
Refactor all plugin loaders in watcher/applier into
watcher/applier/loading/default.py.

Change-Id: I0f0a87d4f72ead45d34aca1b14219fd2ede42a6f
Closes-Bug: #1591095
2016-06-23 02:50:55 -05:00
Alexandr Stavitskiy
cb693e4093 Add importing modules instead of classes
This patch removes import of classes and replaces them with import of modules.

Change-Id: Id2502cf96ac7227cf1036cd54a74f3d7acd83479
Closes-Bug: #1594434
2016-06-22 13:32:34 +03:00
Tin Lam
9918f59227 Centralize plugin loaders in decision engine
Refactor planner loader in watcher/decision_engine/planner/loading/default.py
to watcher/decision_engine/loading/default.py.

Change-Id: I3d4f3668d2269b5a77a35f4470a4d1c96c3128dd
Closes-Bug: #1591092
2016-06-21 23:37:38 -05:00
Vladimir Ostroverkhov
07c7ba9b2e Add goal_name field in strategy
This patch set adds goal_name field in strategy
Related-Bug: #1590416.

Change-Id: Ia381dd882b244487f8beec4d04dabddd1ac7dbc7
2016-06-21 22:16:27 +03:00
OpenStack Proposal Bot
73cf5a98ae Updated from global requirements
Change-Id: I9afbb5b257259f5110471972f98144ed6cb3f621
2016-06-21 18:07:32 +00:00
jinquanni
80abcd6fd9 Use disabled/enabled to change service state
The VM workload consolidation strategy sends 'down' instead
of 'disabled' to change nova-compute service state. This patch
will correct it. The same applies for enabling nova-compute service.

Change-Id: I257411ef711b215bd9b56d0bf0479c79a9ef61d8
Closes-Bug: #1591901
2016-06-21 18:25:14 +08:00
Jenkins
e3edc67045 Merge "Check if nova-service is already disabled" 2016-06-21 08:40:17 +00:00
Bruno Grazioli
b3c2d3af1f Check if nova-service is already disabled
This patch updates VM workload consolidation strategy adding a new
condition to check whether nova-compute service is disabled before
creating the action.

Change-Id: I1accbc7bbd62684dce14ca3b35c92121e923a73a
Closes-Bug: #1591927
2016-06-21 09:54:36 +02:00
Tin Lam
4fc3307525 Add bandit in tox -e pep8
Add bandit tox environment and amend pep8 env to run it.
Also, fix bandit errors with "0.0.0.0".

Change-Id: Ieb5785abd945663e07c07f0ddd3d9a074004f46a
Closes-Bug: #1594423
2016-06-20 19:03:02 -05:00
Vincent Françoise
77c07a466f Added filter operators
In this changeset, I refactored the DB filter system to support
comparison operators using a django-like syntax.
A filter can take 2 forms:

- "<FIELDNAME>" which is a syntactic sugar for "<FIELDNAME>__eq"
- "<FIELDNAME>__<OPERATOR>" where <OPERATOR> is the comparison operator
  to be used.

Here is the list of the supported operators:

- 'eq' (==)
- 'neq' (!=)
- 'gt' (>)
- 'gte' (>=)
- 'lt' (<)
- 'lte' (<=)
- 'in' (in)
- 'notin' (not in)

Change-Id: I53a61d50a3253342a40f0ff87cb5612ed57a3bd1
2016-06-17 10:37:44 +02:00
Jenkins
80867703ba Merge "Added audit_template filter to /audits/detail" 2016-06-17 07:44:53 +00:00
Jean-Emile DARTOIS
7b403c0d3b Fix StrategyContext to use the strategy_id in the Audit Template
This patch fixes the StrategyContext to use the optional
attribute strategy_id.

Change-Id: Ib78581f564282de6cfc7f07495c846615ec1866a
Closed-bug: #1590357
2016-06-15 13:08:28 +02:00
Jenkins
6f2c82316c Merge "Use proper theme for release notes" 2016-06-15 09:05:11 +00:00
Jenkins
b21193aaf2 Merge "Documentation on goal and efficacy" 2016-06-15 09:00:09 +00:00
Jenkins
e1a1cd79f4 Merge "Added efficacy indicators to /action_plans" 2016-06-15 09:00:03 +00:00
Jenkins
019fc498ae Merge "Added pre/post execution methods to strategies" 2016-06-15 08:59:58 +00:00
Jenkins
407a505e73 Merge "Added EfficacyIndicator object" 2016-06-15 08:59:52 +00:00
Jenkins
488c6e3f4e Merge "Added efficacy specification to /goals" 2016-06-15 08:59:46 +00:00
Jenkins
28a2422ceb Merge "Added EfficacyIndicator model in DB" 2016-06-15 08:59:41 +00:00
Jenkins
58b5baaeae Merge "Decoupled Goal from Strategy" 2016-06-15 08:59:38 +00:00
Andreas Jaeger
e8fc4a1bc8 Use proper theme for release notes
Use oslosphinx as theme - watcher is an official project and thus
should use it.

Change-Id: I0ab1ad3e99a92e6b59a4bcb29f216b4af6cbac6a
2016-06-15 10:12:29 +02:00
Andreas Jaeger
921e531adf Fix releasenotes generation
Fix several problems, tox -e releasenotes did not run at all.

Fixes:
* Fix version import so that release note building works.
* There's no stable/mitaka branch for watcher, so remove the mitaka file,
  otherwise release notes build will fail.
* Add _static directory with empty placeholder for sphinx to run.

Change-Id: Ia4dd2f7a7743dfd7f7022be04552c401ade9953f
2016-06-15 09:38:48 +02:00
Jenkins
b5cb6631cc Merge "Add reno for release notes management" 2016-06-13 01:07:10 +00:00
Vincent Françoise
45801cf9c5 Documentation on goal and efficacy
In this changeset, I wrote a documentation detailing how one can
implement a new goal plugin. I also mention to define the efficacy
specification for a given goal.

Partially Implements: blueprint efficacy-indicator

Change-Id: Iba267ae312f248b49d4600504f11678cdc225622
2016-06-10 17:08:28 +02:00
Vincent Françoise
442512cd71 Added efficacy indicators to /action_plans
I this changeset, I added the efficacy indicators both at the DB
and at the API level alongside the associated logic.

Partially Implements: blueprint efficacy-indicator

Change-Id: I824553637621da67966103c1b0c01348b09bd836
2016-06-10 09:37:14 +02:00
Vincent Françoise
2b95a4cbc4 Added pre/post execution methods to strategies
In this changeset, I broke down the execute() method to sequentially
call 3 methods:

- pre_execute()
- do_execute()
- post_execute()

This changeset also removes the cluster model parameter from the
execute() method to now become a `model` property of a strategy which
is lazy loaded whenever needed.

Partially Implements: blueprint efficacy-indicator

Change-Id: I2f697938db693acfa95b2c2fbecfdc1b733c93fd
2016-06-10 09:37:11 +02:00
Vincent Françoise
84b12f8f1e Added EfficacyIndicator object
In this changeset, I created the Watcher object for the efficacy
indicators as well as the API object which will be embedded into the
/action_plans endpoint.

Partially Implements: blueprint efficacy-indicator

Change-Id: Ibbe47613317d51a3829fe9de12540c048e8d7117
2016-06-10 09:37:08 +02:00
Vincent Françoise
f665d83657 Added efficacy specification to /goals
In this changeset, I added the new Efficacy, EfficacySpecification
and IndicatorSpecification classes which are the main components for
computing an efficacy.

Partially Implements: blueprint efficacy-indicator

Change-Id: I3a1d62569de2dd6bb6f9a52f6058313fa2b886ce
2016-06-10 09:36:59 +02:00
Antoine Cabot
5e16e032be Add reno for release notes management
Change-Id: I81337ca27fa639da74cb34a874fbbc6248026c34
2016-06-09 11:01:20 +02:00
Vincent Françoise
eab47bf182 Added EfficacyIndicator model in DB
In this changeset, I created a new model named EfficacyIndicator
which is responsible for storing information regarding the efficacy
indicators that were computed by the strategy in its solution. Every
efficacy indicator should relate to a single Action Plan.

Partially Implements: blueprint efficacy-indicator

Change-Id: Ifc14ea5e16e92f032d7912c9b3fdc270af79cab6
2016-06-08 14:05:01 +02:00
Vincent Françoise
2544327979 Decoupled Goal from Strategy
In this changeset, I decoupled the notion of Goal from the Strategy
by making it a distinct object. Goals are plugins that can be loaded
just like for the strategies.

Partially Implements: blueprint efficacy-indicator

Change-Id: I4378dccd508170b305aa968843228bbc8af78895
2016-06-08 14:00:43 +02:00
Antoine Cabot
2412df4b6c Fix broken link in doc
Change-Id: I4144a9b9d4eec4445e21749a8e71597bb1ad375e
2016-06-08 09:21:52 +02:00
Jenkins
d811dd93ae Merge "Added missing config section for autogeneration" 2016-06-07 13:34:51 +00:00
Vincent Françoise
cb342b45b7 Added missing config section for autogeneration
In this changeset, I added the missing entries for the configuration
sample file generation:

- oslo.reports
- oslo.cache
- oslo.concurrency
- oslo.policy
- oslo.service.periodic_task
- oslo.service.service
- oslo.service.wsgi

Change-Id: I826f5cc1185d75f545c96242022a07089cf3042e
2016-06-06 17:47:13 +02:00
OpenStack Proposal Bot
1a4d5a3df3 Updated from global requirements
Change-Id: I65fc08c423a43aaf5b80d5728038b91c8821da42
2016-06-03 18:21:04 +00:00
Vincent Françoise
8b8d2f01fe Added audit_template filter to /audits/detail
In this changeset, I added the 'audit_template' filter to the
/audits/detail endpoint so it has the same set of parameters as
the /audits endpoint.

Change-Id: I2568be18854bd97d4b7879532cb36a7cac532719
2016-06-03 15:05:59 +02:00
Alexander Chadin
ca37358cac Add fix for hardware.cpu.util meter in sd-strategy
This patch set removes normalizing for hardware.cpu.util meter
since the values that comes from ceilometer hardware.cpu.util
are already normalized.

Closes-Bug: #1588257

Change-Id: I9494f2cc9bbaa6dfd168fb515f679eb6d7f2398a
2016-06-02 13:12:48 +03:00
Jenkins
46091385d8 Merge "Add fix for __init__() error" 2016-06-02 08:46:55 +00:00
Jenkins
a457707e56 Merge "Replace assertEqual(None, *) with assertIsNone in tests" 2016-06-02 07:59:39 +00:00
Jenkins
6c922b43ea Merge "Updated tempest test creds retrieval mechanism" 2016-06-02 07:53:11 +00:00
Alexander Chadin
5d66f66050 Add fix for __init__() error
This patch set fixes __init__() got multiple values
for keyword argument osc error.

Closes-Bug: #1587824

Change-Id: Ieaa1250774ec0fdab5450fe9c3962bb3d1f4136b
2016-06-02 10:48:28 +03:00
Jenkins
e7e50b3955 Merge "Remove direct access to dbapi" 2016-06-02 03:10:31 +00:00
Vincent Françoise
d9a2b8809b Updated tempest test creds retrieval mechanism
Following https://review.openstack.org/#/c/263376/, I update the
way Watcher tempest test retrieve the admin credentials.

Change-Id: I9633752ff69a27edf8912227ea2fd24f358dec7e
2016-05-30 11:45:10 +02:00
Jenkins
3d398b4d22 Merge "Documentation for plugins-parameters" 2016-05-30 09:41:53 +00:00
Jenkins
585fbeb9ee Merge "Watcher plugins table in Guru meditation reports" 2016-05-30 09:41:49 +00:00
Jenkins
e9f237dc80 Merge "Enabled config parameters to plugins" 2016-05-30 09:40:30 +00:00
Vincent Françoise
38f6700144 Documentation for plugins-parameters
In this changeset, I updated the documentation to explain how to
add configuration options for each type of plugin.

Partially Implements: plugins-parameters

Change-Id: Ifd373da64207110492b4a62f1cb7f13b029a45d2
2016-05-30 10:28:29 +02:00
junjie huang
30bdf29002 Workload balance migration strategy implementation
This is one of the algorithm of Intel thermal POC.
It's based on the VM workloads of hypervisors.

Change-Id: I45ab0cf0f05786e6f68025bdd315f38381900a68
blueprint: workload-balance-migration-strategy
2016-05-30 07:52:05 +00:00
Vincent Françoise
e6f147d81d Watcher plugins table in Guru meditation reports
In this changeset, I added the list of all the available plugins
for the current instance of any given Watcher service.

Partially Implements: blueprint plugins-parameters

Change-Id: I58c9724a229712b0322a578f0f89a61b38dfd80a
2016-05-30 09:48:37 +02:00
Vincent Françoise
5aa6b16238 Enabled config parameters to plugins
In this changeset, I added the possibility for all plugins to define
configuration parameters for themselves.

Partially Implements: blueprint plugins-parameters

Change-Id: I676b2583b3b4841c64c862b2b0c234b4eb5fd0fd
2016-05-30 09:48:34 +02:00
Jenkins
dcb5c1f9fc Merge "Add Overload standard deviation strategy" 2016-05-30 07:10:17 +00:00
Jenkins
4ba01cbbcf Merge "Update Watcher documentation" 2016-05-27 15:58:01 +00:00
Jenkins
d91d72d2c2 Merge "Add goal name as filter for strategy list cmd" 2016-05-27 15:51:22 +00:00
Jenkins
083bc2bed4 Merge "Add goal_name & strategy_name in /audit_templates" 2016-05-27 15:51:14 +00:00
Alexander Chadin
9d3671af37 Add Overload standard deviation strategy
The main purpose of this strategy is to choose the pair VM:dest_host that
minimizes the standard deviation in a cluster best.

Change-Id: I95a31b7bcab83411ef6b6e1e01818ca21ef96883
Implements: blueprint watcher-overload-sd
2016-05-27 16:16:36 +03:00
Jenkins
3b88e37680 Merge "Added cold VM migration support" 2016-05-27 12:33:46 +00:00
David TARDIVEL
6eee64502f Add goal name as filter for strategy list cmd
This changeset add the possibility to use the goal name as a
stragegy list filter.

Change-Id: Ibaf45e694f115308f19e9bcd3023fe2e6d1750cd
2016-05-27 11:20:55 +02:00
David TARDIVEL
b9231f65cc Update Watcher documentation
We introduced a new watcher plugin for OpenStack CLI. This patchset
updates accordingly the watcher documentation and schemas.

Partially Implements: blueprint openstackclient-plugin

Change-Id: Ib00469c8645fff21f5ba95951379827dbd359c69
2016-05-27 09:40:06 +02:00
OpenStack Proposal Bot
b9b505a518 Updated from global requirements
Change-Id: Ia90ce890fac40ddb6d38effd022ca71e9a7fc52f
2016-05-26 17:07:34 +00:00
cima
388ef9f11c Added cold VM migration support
Cold migration enables migrating some of the VMs which are not in active state (e.g. stopped). Cold migration can also be used for migrating active VM, although VM is shut down and hence unaccessible while migrating.

Change-Id: I89ad0a04d41282431c9773f6ae7feb41573368e3
Closes-Bug: #1564297
2016-05-24 13:26:45 +02:00
Jenkins
4e3caaa157 Merge "Fixed flaky tempest test" 2016-05-24 09:25:15 +00:00
Vincent Françoise
8c6bf734af Add goal_name & strategy_name in /audit_templates
In this changeset, I added both the 'goal_name' and the 'strategy_name'
field.

Change-Id: Ic164df84d4e23ec75b2b2f4b358cf827d0ad7fa5
Related-Bug: #1573582
2016-05-24 11:09:48 +02:00
sharat.sharma
164a802718 Replace assertEqual(None, *) with assertIsNone in tests
Replace assertEqual(None, *) with assertIsNone in tests to have
more clear messages in case of failure.

Change-Id: I98261ef7cca06447ea9d443a2c287c046f380f77
Closes-Bug: #1280522
2016-05-23 18:05:19 +05:30
Vincent Françoise
277a749ca0 Fix lazy translation issue with watcher-db-manage
In this changeset, I fix the issue caused by the use of lazy
translations within the 'watcher-db-manage purge' subcommand.
This is caused by the PrettyTable dependency which performs
addition operations to format its tables and the __add__ magic
method is not supported by oslo_i18n._message.Message objects.

Change-Id: Idd590e882c697957cfaf1849c3d51b52797230f6
Closes-Bug: #1584652
2016-05-23 14:35:17 +02:00
Vincent Françoise
8401b5e479 Fixed flaky tempest test
In this changeset, I fixed the test_create_audit_with_no_state
tempest test which was randomly failing because of a race condition.

Change-Id: Ibda49944c79fcd406fa81870dbbff6064b5dc4fa
2016-05-23 14:32:44 +02:00
Vincent Françoise
78689fbe3b Removed telemetry tag from tempest tests
Since telemetry was removed from tempest, this changeset removes the
telemetry tags from the watcher integration tests

Change-Id: I6229ee23740c3d92a66fc04c8de8b0ed25911022
2016-05-23 09:22:31 +00:00
OpenStack Proposal Bot
22abaa9c3a Updated from global requirements
Change-Id: I2506d35432748691fb53f8540aac43d1656a67a3
2016-05-21 15:53:55 +00:00
Alexander Chadin
fb82131d85 Fix for statistic_aggregation
This patch set fixes aggregate parameter for statistic_aggregation
function so we may use it with any aggregate function.

Change-Id: If586d656aadd3d098a1610a97a2f315e70351de5
Closes-Bug: #1583610
2016-05-19 16:41:07 +03:00
Jenkins
f6f5079adb Merge "Watcher DB class diagram" 2016-05-18 12:36:17 +00:00
Tin Lam
dbdf690cd0 Remove direct access to dbapi
In line [1], we directly use the dbapi in order to
filter the actions by action_plan_id.

[1] https://github.com/openstack/watcher/blob/master/watcher/applier/default.py#L63

Change-Id: I2c75528f619a5277d46702cc3b4ca4bc7280f990
Closes-Bug: #1534170
2016-05-17 18:27:41 -05:00
Jenkins
f045f5d816 Merge "Updated from global requirements" 2016-05-13 07:06:35 +00:00
Jenkins
b77541deb2 Merge "[nova_helper] get keypair name by every admin users" 2016-05-13 06:33:42 +00:00
OpenStack Proposal Bot
3b9d72439c Updated from global requirements
Change-Id: I0f4fe97bdfa872074964a10535db868354d926da
2016-05-11 17:29:55 +00:00
Jenkins
89aa2d54df Merge "Added .pot file" 2016-05-11 15:39:13 +00:00
Jenkins
86f4cee588 Merge "Remove [watcher_goals] config section" 2016-05-11 15:32:36 +00:00
Jenkins
04ac509821 Merge "Remove watcher_goals section from devstack plugin" 2016-05-11 15:32:35 +00:00
Jenkins
4ba9d2cb73 Merge "Documentation update for get-goal-from-strategy" 2016-05-11 15:32:28 +00:00
Jenkins
a71c9be860 Merge "Updated purge to now include goals and strategies" 2016-05-11 15:32:22 +00:00
Jenkins
c2cb1a1f8e Merge "Syncer now syncs stale audit templates" 2016-05-11 15:32:17 +00:00
Jenkins
79bdcf7baf Merge "Add strategy_id & goal_id fields in audit template" 2016-05-11 15:32:10 +00:00
Jenkins
de1b1a9938 Merge "Refactored Strategy selector to select from DB" 2016-05-11 15:32:07 +00:00
Jenkins
031ebdecde Merge "Added /strategies endpoint in Watcher API" 2016-05-11 15:32:01 +00:00
Jenkins
daabe671c7 Merge "Add Goal in BaseStrategy + Goal API reads from DB" 2016-05-11 15:31:58 +00:00
Jenkins
26bc3d139d Merge "DB sync for Strategies" 2016-05-11 15:31:39 +00:00
Jenkins
4d2536b9b2 Merge "Added Strategy model" 2016-05-11 15:30:46 +00:00
Jenkins
4388780e66 Merge "Added Goal object + goal syncing" 2016-05-11 15:29:21 +00:00
Jenkins
d03a9197b0 Merge "Added Goal model into Watcher DB" 2016-05-11 15:28:28 +00:00
Jean-Emile DARTOIS
43f5ab18ba Fix documentation watcher sql database
This changeset fixes the issue with the parameter watcher-db-manage

Change-Id: I668edd85e3ea40c2a309caacbf68cf35bfd680f7
Closes-Bug: #1580617
2016-05-11 15:58:46 +02:00
Vincent Françoise
209176c3d7 Watcher DB class diagram
In this changeset, I added a class diagram reprensenting the
database schema of Watcher.

Change-Id: I2257010d0040a3f40279ec9db2967f0e69384b62
2016-05-11 15:52:54 +02:00
Vincent Françoise
1a21867735 Added .pot file
In this changeset, I just generate the .pot file for all the new
translations that were added during the implementation of this BP

Partially Implements: blueprint get-goal-from-strategy

Change-Id: I2192508afda037510f8f91092c5cfde0115dae1d
2016-05-11 15:48:09 +02:00
Vincent Françoise
5f6a97148f Remove [watcher_goals] config section
In this changeset, I remove the now unused [watcher_goals] section.

Partially Implements: blueprint get-goal-from-strategy

Change-Id: I91e4e1ac3a58bb6f3e30b11449cf1a6eb18cd0ca
2016-05-11 15:48:09 +02:00
Vincent Françoise
e6b23a0856 Remove watcher_goals section from devstack plugin
In this changeset, I removed the now useless [watcher_goals] section
from the devstack plugin.

Partially Implements: blueprint get-goal-from-strategy

Change-Id: Iaa986f426dc47f6cbd04e74f16b67670e3563967
2016-05-11 15:48:09 +02:00
Vincent Françoise
f9a1b9d3ce Documentation update for get-goal-from-strategy
In this changeset, I updated the Watcher documentation to reflect
the changes that are introduced by this blueprint.

Partially Implements: blueprint get-goal-from-strategy

Change-Id: I40be39624097365220bf7d94cbe177bbf5bbe0ed
2016-05-11 15:48:02 +02:00
Vincent Françoise
ff611544fb Updated purge to now include goals and strategies
In this changeset, I updated the purge script to now take into
account the registered goals and strategies.

Partially Implements: blueprint get-goal-from-strategy

Change-Id: I2f1d58bb812fa45bc4bc6467760a071d8612e6a4
2016-05-11 15:31:02 +02:00
Vincent Françoise
18e5c7d844 Syncer now syncs stale audit templates
In this changeset, I introduce the syncing of audit templates.

Partially Implements: blueprint get-goal-from-strategy

Change-Id: Ie394c12fe51f73eff95465fd5140d82ebd212599
2016-05-11 15:31:02 +02:00
Vincent Françoise
2966b93777 Add strategy_id & goal_id fields in audit template
In this changeset, I updated the 'goal_id' field into the AuditTemplate
to now become a mandatory foreign key towards the Goal model. I also
added the 'strategy_id' field into the AuditTemplate model to be an
optional foreign key onto the Strategy model.

This changeset also includes an update of the /audit_template
Watcher API endpoint to reflect the previous changes.

As this changeset changes the API, this should be merged alongside the
related changeset from python-watcherclient.

Partially Implements: blueprint get-goal-from-strategy

Change-Id: Ic0573d036d1bbd7820f8eb963e47912d6b3ed1a9
2016-05-11 15:31:02 +02:00
Vincent Françoise
e67b532110 Refactored Strategy selector to select from DB
In this changeset, I refactored the strategy selector to now
look into the Watcher DB instead of looking into the configuration
file.

Partially Implements: blueprint get-goal-from-strategy

Change-Id: I2bcb63542f6237f26796a3e5a781c8b62820cf6f
2016-05-11 15:31:01 +02:00
Vincent Françoise
81765b9aa5 Added /strategies endpoint in Watcher API
In this changeset, I added the /strategies endpoint to the Watcher
API service.
This also includes the related Tempest tests.

Partially Implements: blueprint get-goal-from-strategy

Change-Id: I1b70836e0df2082ab0016ecc207e89fdcb0fc8b9
2016-05-11 15:31:01 +02:00
Vincent Françoise
673642e436 Add Goal in BaseStrategy + Goal API reads from DB
In this changeset, I changed the Strategy base class to add new
abstract class methods. I also added an abstract strategy class
per Goal type (dummy, server consolidation, thermal optimization).

This changeset also includes an update of the /goals Watcher API
endpoint to now use the new Goal model (DB entries) instead of
reading from the configuration file.

Partially Implements: blueprint get-goal-from-strategy
Change-Id: Iecfed58c72f3f9df4e9d27e50a3a274a1fc0a75f
2016-05-11 15:31:00 +02:00
Jenkins
1026a896e2 Merge "Log "https" if using SSL" 2016-05-11 13:24:43 +00:00
Vincent Françoise
a3ac26870a DB sync for Strategies
In this changeset, I added the ability to synchronize the strategies
into the Wather DB so that it can later be served through the Watcher
API.

Partially Implements: blueprint get-goal-from-strategy

Change-Id: Ifeaa1f6e1f4ff7d7efc1b221cf57797a49dc5bc5
2016-05-11 15:19:40 +02:00
Vincent Françoise
192d8e262c Added Strategy model
In this changeset, I add the Strategy model as well as the DB
functionalities we need to manipulate strategies.

This changeset implies a DB schema update.

Partially Implements: blueprint get-goal-from-strategy

Change-Id: I438a8788844fbc514edfe1e9e3136f46ba5a82f2
2016-05-11 15:19:40 +02:00
Vincent Françoise
3b5ef15db6 Added Goal object + goal syncing
In this changeset, I added the Goal object into Watcher along with
a sync module that is responsible for syncing the goals with the
Watcher DB.

Partially Implements: blueprint get-goal-from-strategy

Change-Id: Ia3a2032dd9023d668c6f32ebbce44f8c1d77b0a3
2016-05-11 15:19:40 +02:00
Vincent Françoise
be9058f3e3 Added Goal model into Watcher DB
In this changeset, I added the Goal model into Watcher.
This implies a change into the Watcher DB schema

Partially Implements: blueprint get-goal-from-strategy

Change-Id: I5b5b0ffc7cff8affb59f17743e1af0e1277c2878
2016-05-11 15:19:40 +02:00
Jenkins
91951f3b01 Merge "Refactored DE and Applier to use oslo.service" 2016-05-11 13:14:52 +00:00
Jenkins
57a2af2685 Merge "Refactored Watcher API service" 2016-05-11 13:14:29 +00:00
Yosef Hoffman
76e3d2e2f6 Log "https" if using SSL
When starting the Watcher API service, the URI it served to is shown in
a log message. In this log message (in watcher/cmd/api.py) take into
account the case where SSL has been enabled with CONF.api.enable_ssl_api
set to True and format this log message accordingly.

Change-Id: I98541810139d9d4319ac89f21a5e0bc25454ee62
Closes-Bug: #1580044
2016-05-10 11:44:56 -04:00
Jenkins
bd5a969a26 Merge "Remove using of UUID field in POST methods of Watcher API" 2016-04-29 02:57:34 +00:00
zhangguoqing
d61bf5f053 [nova_helper] get keypair name by every admin users
Since the bug #1182965 has been fixed, allow admin users
to view any keypair.

Change-Id: I9cf948701515afd45e6720cfd15cfac6b5866aa5
2016-04-25 21:20:16 +08:00
Alexander Chadin
aaaf3f1c84 Remove using of UUID field in POST methods of Watcher API
This patch set removes the possibility of using UUID field
in POST methods of Watcher API.

Closes-Bug: #1572625

Change-Id: I88a8aa5346e937e3e9409b55da3316cbe1ed832a
2016-04-25 16:05:59 +03:00
Vincent Françoise
eb861f86ab Refactored DE and Applier to use oslo.service
In this PS, I have refactored the Decision Engine and the Applier
to use the oslo service utility.

Change-Id: If29158cc9b5e5e50f6c69d67c232cceeb07084f2
Closes-Bug: #1541850
2016-04-22 10:33:21 +02:00
Vincent Françoise
a9e7251d0d Refactored Watcher API service
This patchset introduces the use of oslo.service to run the
Watcher API service.

Change-Id: I6c38a3c1a2b4dc47388876e4c0ba61b7447690bd
Related-Bug: #1541850
2016-04-22 10:33:21 +02:00
OpenStack Proposal Bot
4ff373197c Updated from global requirements
Change-Id: I04865b9e63d6fc805802b6057ba9750116849c98
2016-04-19 12:30:29 +00:00
Jenkins
87087e9add Merge "Removed unused 'alarm' field" 2016-04-19 08:02:21 +00:00
Larry Rensing
408d6d4650 Removed unused 'alarm' field
The 'alarm' field is currently unused, so it has been removed.

Change-Id: I02fa15b06ed49dbc5dd63de54a9cde601413983c
Closes-Bug: #1550261
2016-04-18 14:12:12 +00:00
Alexander Chadin
e52dc4f8aa Add parameters verification when Audit is being created
We have to check Audit Type and Audit State to make sure
these parameters are in valid status.

Also, we provide default states for the next attributes:

- 'audit_template' is required and should be either UUID or text field
- 'state' is readonly so it raises an error if submitted in POST
  and is set by default to PENDING
- 'deadline' is optional and should be a datetime
- 'type' is a required text field

Change-Id: I2a7e0deec0ee2040e86400b500bb0efd8eade564
Closes-Bug: #1532843
Closes-Bug: #1533210
2016-04-14 15:43:26 +03:00
Jenkins
0f14b7635d Merge "correct the available disk, memory calculating Source data are misused in outlet temperature strategy. This patch fixes it." 2016-04-12 07:08:15 +00:00
junjie huang
bb77641aad correct the available disk, memory calculating
Source data are misused in outlet temperature strategy. This patch
fixes it.

Change-Id: I8ad5c974d7674ddfe6c4c9e3a6e3029d34a400db
Closes-bug: #1569114
2016-04-11 17:53:54 +00:00
Vincent Françoise
77228a0b0a Upgrade Watcher Tempest tests for multinode
Change-Id: I4b84ba9814227776232c8ab883cdaaf411930ee6
2016-04-11 16:49:10 +02:00
Jenkins
1157a8db30 Merge "Fix for deleting audit template" 2016-04-08 18:58:07 +00:00
Jenkins
18354d1b4e Merge "Update .coveragerc to ignore abstract methods" 2016-04-08 18:57:11 +00:00
Larry Rensing
8387cd10de Update .coveragerc to ignore abstract methods
Due to importing modules rather than functions and decorators directly,
@abc.abstract and 'raise NotImplementedError' were added to the
.coveragerc file.  Since abstract methods are not testable, this will
give us a more accurate representation of our coverage.

Change-Id: Id5ed5e1f5e142d10f41ad18d20228399226ec20d
Co-Authored-By: Jin Li <jl7351@att.com>
Closes-Bug: #1563717
2016-04-08 16:59:57 +00:00
OpenStack Proposal Bot
0449bae747 Updated from global requirements
Change-Id: Ieead2a4c784c248bd6af821f5e1e84c5e6cd3b5a
2016-04-07 17:25:39 +00:00
Alexander Chadin
3e07844844 Fix for deleting audit template
We need to update sqlalchemy/api and sqlalchemy/models (and appropriate tests)
to support deleting audit templates and recreating them with the same names.

Change-Id: Icf54cf1ed989a3f2ad689e25be4474b16a3a3eb2
Related-Bug: #1510179
2016-04-07 11:27:53 +03:00
zhangguoqing
a52d92be87 Remove unused logging import and LOG global var
In some modules the global LOG is not used any more. And the import
of logging is not used. This patch removes the unused logging import
and LOG vars.

Change-Id: I794ee719d76f04e70154cf67f726152fbb1ba15a
2016-04-06 10:34:39 +08:00
OpenStack Proposal Bot
96683a6133 Updated from global requirements
Change-Id: Ib98e484bb216eb31b64931db735ced8d1de738a4
2016-04-05 13:44:07 +00:00
Jenkins
46d5094add Merge "Added information on plugin mechanism to glossary" 2016-04-05 07:52:55 +00:00
Jenkins
783c7c0177 Merge "Disabled PATCH, POST and DELETE for /actions" 2016-04-05 07:30:23 +00:00
Jenkins
6d0717199c Merge "Invalid states for Action Plan in the glossary" 2016-04-05 07:27:12 +00:00
cima
8b77e78f3d Added missing support for resource states in unicode format in VM workload consolidation strategy
Unicode type resource state is now handled in the same fashion as resource state specified by general string.

Change-Id: I35ffa09015283b51c935515436735aecbe83a9d6
Closes-Bug: #1565764
2016-04-04 15:17:35 +02:00
Vincent Françoise
22c9c4df87 Disabled PATCH, POST and DELETE for /actions
I removed the POST, PATCH and DELETE verbs from the actions
controller as they should only be modified internally.

Change-Id: Ia72484249240f829423056f66c5c0f9632d02106
Closes-Bug: #1533281
2016-03-30 10:10:28 +02:00
Jenkins
99ff6d3348 Merge "Integrated consolidation strategy with watcher" 2016-03-29 15:36:28 +00:00
Tin Lam
c67f83cce0 Added information on plugin mechanism to glossary
Added extra information regarding the plugin mechanism for:
action, strategy, and Watcher planner.

Change-Id: I9a7523282e229b83c16b06e3806ff795a0699c78
Closes-Bug: #1558470
2016-03-24 18:42:17 -05:00
Larry Rensing
397bb3497e Invalid states for Action Plan in the glossary
The list of possible states for Action Plan objects was outdated, and
was updated to match the state machine diagram.  A reference to the
state machines for Audits and Action Plans were added to the glossary,
and the descriptions of each state were moved to the sections containing
the state machines within the Architecture page.

Change-Id: I27043ad864c02fff50fb31868b27dc4b4897dbd4
Closes-Bug: #1558464
2016-03-24 15:14:42 +00:00
Bruno Grazioli
4c924fc505 Integrated consolidation strategy with watcher
This patch adds a new load consolidation strategy based on a heuristic
algorithm which focuses on measured CPU utilization and tries to
minimize hosts which have too much or too little load.
A new goal "vm_workload_consolidation" was added which executes
the strategy "VM_WORKLOAD_CONSOLIDATION".
This work depends on the implemetation of the bug:
https://bugs.launchpad.net/watcher/+bug/1553124

Change-Id: Ide05bddb5c85a3df05b94658ee5bd98f32e554b0
Implements: blueprint basic-cloud-consolidation-integration
2016-03-24 12:00:01 +01:00
jaugustine
4c5ecc808d Added oslo.context to requirements.txt
Added missing dependency oslo.context to requirements.txt

Change-Id: I88c42fd2381bad55ff499e096a93dcc2cc1d44e5
Closes-Bug: #1560976
2016-03-23 10:45:23 -05:00
476 changed files with 37778 additions and 9970 deletions

View File

@@ -1,9 +1,12 @@
[run]
branch = True
source = watcher
omit = watcher/tests/*
omit =
watcher/tests/*
watcher/hacking/*
[report]
ignore_errors = True
ignore_errors = True
exclude_lines =
@abstract
@abc.abstract
raise NotImplementedError

7
.gitignore vendored
View File

@@ -64,3 +64,10 @@ sftp-config.json
cover
/demo/
# Files created by releasenotes build
releasenotes/build
# Desktop Service Store
*.DS_Store

View File

@@ -1,6 +0,0 @@
include AUTHORS
include ChangeLog
exclude .gitignore
exclude .gitreview
global-exclude *.pyc

View File

@@ -1,3 +1,12 @@
========================
Team and repository tags
========================
.. image:: http://governance.openstack.org/badges/watcher.svg
:target: http://governance.openstack.org/reference/tags/index.html
.. Change things from this point on
..
Except where otherwise noted, this document is licensed under Creative
Commons Attribution 3.0 License. You can view the license at:
@@ -10,10 +19,8 @@ Watcher
OpenStack Watcher provides a flexible and scalable resource optimization
service for multi-tenant OpenStack-based clouds.
Watcher provides a complete optimization loop-including everything from a
metrics receiver, complex event processor and profiler, optimization processor
and an action plan applier. This provides a robust framework to realize a wide
range of cloud optimization goals, including the reduction of data center
Watcher provides a robust framework to realize a wide range of cloud
optimization goals, including the reduction of data center
operating costs, increased system performance via intelligent virtual machine
migration, increased energy efficiency-and more!
@@ -21,4 +28,4 @@ migration, increased energy efficiency-and more!
* Wiki: http://wiki.openstack.org/wiki/Watcher
* Source: https://github.com/openstack/watcher
* Bugs: http://bugs.launchpad.net/watcher
* Documentation: https://factory.b-com.com/www/watcher/doc/watcher/index.html
* Documentation: http://docs.openstack.org/developer/watcher/

View File

@@ -44,6 +44,9 @@ WATCHER_CONF_DIR=/etc/watcher
WATCHER_CONF=$WATCHER_CONF_DIR/watcher.conf
WATCHER_POLICY_JSON=$WATCHER_CONF_DIR/policy.json
NOVA_CONF_DIR=/etc/nova
NOVA_CONF=$NOVA_CONF_DIR/nova.conf
if is_ssl_enabled_service "watcher" || is_service_enabled tls-proxy; then
WATCHER_SERVICE_PROTOCOL="https"
fi
@@ -123,6 +126,11 @@ function create_watcher_conf {
iniset $WATCHER_CONF oslo_messaging_rabbit rabbit_password $RABBIT_PASSWORD
iniset $WATCHER_CONF oslo_messaging_rabbit rabbit_host $RABBIT_HOST
iniset $WATCHER_CONF oslo_messaging_notifications driver "messaging"
iniset $NOVA_CONF oslo_messaging_notifications topics "notifications,watcher_notifications"
iniset $NOVA_CONF notifications notify_on_state_change "vm_and_task_state"
configure_auth_token_middleware $WATCHER_CONF watcher $WATCHER_AUTH_CACHE_DIR
configure_auth_token_middleware $WATCHER_CONF watcher $WATCHER_AUTH_CACHE_DIR "watcher_clients_auth"

View File

@@ -44,3 +44,6 @@ LOGDAYS=2
[[post-config|$NOVA_CONF]]
[DEFAULT]
compute_monitors=cpu.virt_driver
notify_on_state_change = vm_and_task_state
[notifications]
notify_on_state_change = vm_and_task_state

View File

@@ -27,6 +27,9 @@ ENABLED_SERVICES+=,q-svc,q-dhcp,q-meta,q-agt,q-l3,neutron
# Enable remote console access
enable_service n-cauth
# Enable the Watcher Dashboard plugin
# enable_plugin watcher-dashboard git://git.openstack.org/openstack/watcher-dashboard
# Enable the Watcher plugin
enable_plugin watcher git://git.openstack.org/openstack/watcher
@@ -42,7 +45,6 @@ LOGDAYS=2
[[post-config|$NOVA_CONF]]
[DEFAULT]
compute_monitors=cpu.virt_driver
[[post-config|$WATCHER_CONF]]
[watcher_goals]
goals=BASIC_CONSOLIDATION:basic,DUMMY:dummy
notify_on_state_change = vm_and_task_state
[notifications]
notify_on_state_change = vm_and_task_state

View File

@@ -1,4 +1,3 @@
# -*- encoding: utf-8 -*-
# Copyright (c) 2015 b<>com
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -22,7 +21,6 @@ import inspect
from docutils import nodes
from docutils.parsers import rst
from docutils import statemachine
from stevedore import extension
from watcher.version import version_info
@@ -57,7 +55,7 @@ class BaseWatcherDirective(rst.Directive):
if not obj_raw_docstring:
# Raise a warning to make the tests fail wit doc8
raise self.error("No docstring available for this plugin!")
raise self.error("No docstring available for %s!" % obj)
obj_docstring = inspect.cleandoc(obj_raw_docstring)
self.add_textblock(obj_docstring)
@@ -76,7 +74,7 @@ class WatcherTerm(BaseWatcherDirective):
# Inside your .rst file
.. watcher-term:: import.path.to.your.DocumentedObject
This directive will then import the docstring and then interprete it.
This directive will then import the docstring and then interpret it.
"""
# You need to put an import path as an argument for this directive to work
@@ -86,7 +84,12 @@ class WatcherTerm(BaseWatcherDirective):
cls_path = self.arguments[0]
try:
cls = importlib.import_module(cls_path)
try:
cls = importlib.import_module(cls_path)
except ImportError:
module_name, cls_name = cls_path.rsplit('.', 1)
mod = importlib.import_module(module_name)
cls = getattr(mod, cls_name)
except Exception as exc:
raise self.error(exc)
@@ -98,74 +101,72 @@ class WatcherTerm(BaseWatcherDirective):
return node.children
class DriversDoc(BaseWatcherDirective):
"""Directive to import an RST formatted docstring into the Watcher doc
This directive imports the RST formatted docstring of every driver declared
within an entry point namespace provided as argument
class WatcherFunc(BaseWatcherDirective):
"""Directive to import a value returned by a func into the Watcher doc
**How to use it**
# inside your .py file
class DocumentedClassReferencedInEntrypoint(object):
'''My *.rst* docstring'''
class Bar(object):
def foo(object):
return foo_string
def foo(self):
'''Foo docstring'''
# Inside your .rst file
.. drivers-doc:: entrypoint_namespace
:append_methods_doc: foo
.. watcher-func:: import.path.to.your.Bar.foo node_classname
This directive will then import the docstring and then interprete it.
node_classname is decumented here:
http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html
Note that no section/sub-section can be imported via this directive as it
is a Sphinx restriction.
This directive will then import the value and then interpret it.
"""
# You need to put an import path as an argument for this directive to work
required_arguments = 1
optional_arguments = 0
final_argument_whitespace = True
has_content = False
# required_arguments = 1
# optional_arguments = 1
option_spec = dict(
# CSV formatted list of method names whose return values will be zipped
# together in the given order
append_methods_doc=lambda opts: [
opt.strip() for opt in opts.split(",") if opt.strip()],
# By default, we always start by adding the driver object docstring
exclude_driver_docstring=rst.directives.flag,
)
option_spec = {'format': rst.directives.unchanged}
has_content = True
def run(self):
ext_manager = extension.ExtensionManager(namespace=self.arguments[0])
extensions = ext_manager.extensions
# Aggregates drivers based on their module name (i.e import path)
classes = [(ext.name, ext.plugin) for ext in extensions]
if not self.content:
error = self.state_machine.reporter.error(
'The "%s" directive is empty; content required.' % self.name,
nodes.literal_block(self.block_text, self.block_text),
line=self.lineno)
return [error]
for name, cls in classes:
self.add_line(".. rubric:: %s" % name)
self.add_line("")
func_path = self.content[0]
try:
cls_path, func_name = func_path.rsplit('.', 1)
module_name, cls_name = cls_path.rsplit('.', 1)
mod = importlib.import_module(module_name)
cls = getattr(mod, cls_name)
except Exception as exc:
raise self.error(exc)
if "exclude_driver_docstring" not in self.options:
self.add_object_docstring(cls)
self.add_line("")
cls_obj = cls()
func = getattr(cls_obj, func_name)
textblock = func()
if not isinstance(textblock, str):
textblock = str(textblock)
for method_name in self.options.get("append_methods_doc", []):
if hasattr(cls, method_name):
method = getattr(cls, method_name)
method_result = inspect.cleandoc(method)
self.add_textblock(method_result())
self.add_line("")
self.add_textblock(textblock)
node = nodes.paragraph()
try:
node_class = getattr(nodes,
self.options.get('format', 'paragraph'))
except Exception as exc:
raise self.error(exc)
node = node_class()
node.document = self.state.document
self.state.nested_parse(self.result, 0, node)
return node.children
return [node]
def setup(app):
app.add_directive('drivers-doc', DriversDoc)
app.add_directive('watcher-term', WatcherTerm)
app.add_directive('watcher-func', WatcherFunc)
return {'version': version_info.version_string()}

View File

@@ -0,0 +1,133 @@
# 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.
"""
This provides a sphinx extension able to list the implemented versioned
notifications into the developer documentation.
It is used via a single directive in the .rst file
.. versioned_notifications::
"""
from sphinx.util.compat import Directive
from docutils import nodes
from watcher.notifications import base as notification
from watcher.objects import base
class VersionedNotificationDirective(Directive):
SAMPLE_ROOT = 'doc/notification_samples/'
TOGGLE_SCRIPT = """
<script>
jQuery(document).ready(function(){
jQuery('#%s-div').toggle('show');
jQuery('#%s-hideshow').on('click', function(event) {
jQuery('#%s-div').toggle('show');
});
});
</script>
"""
def run(self):
notifications = self._collect_notifications()
return self._build_markup(notifications)
def _collect_notifications(self):
base.WatcherObjectRegistry.register_notification_objects()
notifications = []
ovos = base.WatcherObjectRegistry.obj_classes()
for name, cls in ovos.items():
cls = cls[0]
if (issubclass(cls, notification.NotificationBase) and
cls != notification.NotificationBase):
payload_name = cls.fields['payload'].objname
payload_cls = ovos[payload_name][0]
for sample in cls.samples:
notifications.append((cls.__name__,
payload_cls.__name__,
sample))
return sorted(notifications)
def _build_markup(self, notifications):
content = []
cols = ['Event type', 'Notification class', 'Payload class', 'Sample']
table = nodes.table()
content.append(table)
group = nodes.tgroup(cols=len(cols))
table.append(group)
head = nodes.thead()
group.append(head)
for _ in cols:
group.append(nodes.colspec(colwidth=1))
body = nodes.tbody()
group.append(body)
# fill the table header
row = nodes.row()
body.append(row)
for col_name in cols:
col = nodes.entry()
row.append(col)
text = nodes.strong(text=col_name)
col.append(text)
# fill the table content, one notification per row
for name, payload, sample_file in notifications:
event_type = sample_file[0: -5].replace('-', '.')
row = nodes.row()
body.append(row)
col = nodes.entry()
row.append(col)
text = nodes.literal(text=event_type)
col.append(text)
col = nodes.entry()
row.append(col)
text = nodes.literal(text=name)
col.append(text)
col = nodes.entry()
row.append(col)
text = nodes.literal(text=payload)
col.append(text)
col = nodes.entry()
row.append(col)
with open(self.SAMPLE_ROOT + sample_file, 'r') as f:
sample_content = f.read()
event_type = sample_file[0: -5]
html_str = self.TOGGLE_SCRIPT % ((event_type, ) * 3)
html_str += ("<input type='button' id='%s-hideshow' "
"value='hide/show sample'>" % event_type)
html_str += ("<div id='%s-div'><pre>%s</pre></div>"
% (event_type, sample_content))
raw = nodes.raw('', html_str, format="html")
col.append(raw)
return content
def setup(app):
app.add_directive('versioned_notifications',
VersionedNotificationDirective)

View File

@@ -0,0 +1,69 @@
{
"priority": "INFO",
"payload": {
"watcher_object.data": {
"audit_type": "ONESHOT",
"parameters": {
"para2": "hello",
"para1": 3.2
},
"state": "PENDING",
"updated_at": null,
"deleted_at": null,
"goal": {
"watcher_object.data": {
"uuid": "bc830f84-8ae3-4fc6-8bc6-e3dd15e8b49a",
"name": "dummy",
"updated_at": null,
"deleted_at": null,
"efficacy_specification": [],
"created_at": "2016-11-04T16:25:35Z",
"display_name": "Dummy goal"
},
"watcher_object.name": "GoalPayload",
"watcher_object.version": "1.0",
"watcher_object.namespace": "watcher"
},
"interval": null,
"scope": [],
"strategy": {
"watcher_object.data": {
"parameters_spec": {
"properties": {
"para2": {
"type": "string",
"default": "hello",
"description": "string parameter example"
},
"para1": {
"description": "number parameter example",
"maximum": 10.2,
"type": "number",
"default": 3.2,
"minimum": 1.0
}
}
},
"name": "dummy",
"uuid": "75234dfe-87e3-4f11-a0e0-3c3305d86a39",
"updated_at": null,
"deleted_at": null,
"created_at": "2016-11-04T16:25:35Z",
"display_name": "Dummy strategy"
},
"watcher_object.name": "StrategyPayload",
"watcher_object.version": "1.0",
"watcher_object.namespace": "watcher"
},
"created_at": "2016-11-04T16:29:20Z",
"uuid": "4a97b9dd-2023-43dc-b713-815bdd94d4d6"
},
"watcher_object.name": "AuditCreatePayload",
"watcher_object.version": "1.0",
"watcher_object.namespace": "watcher"
},
"publisher_id": "infra-optim:localhost",
"timestamp": "2016-11-04 16:31:36.264673 ",
"event_type": "audit.create",
"message_id": "cbcf9f2c-7c53-4b4d-91ec-db49cca024b6"
}

View File

@@ -0,0 +1,69 @@
{
"priority": "INFO",
"payload": {
"watcher_object.data": {
"audit_type": "ONESHOT",
"parameters": {
"para2": "hello",
"para1": 3.2
},
"state": "DELETED",
"updated_at": null,
"deleted_at": null,
"goal": {
"watcher_object.data": {
"uuid": "bc830f84-8ae3-4fc6-8bc6-e3dd15e8b49a",
"name": "dummy",
"updated_at": null,
"deleted_at": null,
"efficacy_specification": [],
"created_at": "2016-11-04T16:25:35Z",
"display_name": "Dummy goal"
},
"watcher_object.name": "GoalPayload",
"watcher_object.version": "1.0",
"watcher_object.namespace": "watcher"
},
"interval": null,
"scope": [],
"strategy": {
"watcher_object.data": {
"parameters_spec": {
"properties": {
"para2": {
"type": "string",
"default": "hello",
"description": "string parameter example"
},
"para1": {
"description": "number parameter example",
"maximum": 10.2,
"type": "number",
"default": 3.2,
"minimum": 1.0
}
}
},
"name": "dummy",
"uuid": "75234dfe-87e3-4f11-a0e0-3c3305d86a39",
"updated_at": null,
"deleted_at": null,
"created_at": "2016-11-04T16:25:35Z",
"display_name": "Dummy strategy"
},
"watcher_object.name": "StrategyPayload",
"watcher_object.version": "1.0",
"watcher_object.namespace": "watcher"
},
"created_at": "2016-11-04T16:29:20Z",
"uuid": "4a97b9dd-2023-43dc-b713-815bdd94d4d6"
},
"watcher_object.name": "AuditDeletePayload",
"watcher_object.version": "1.0",
"watcher_object.namespace": "watcher"
},
"publisher_id": "infra-optim:localhost",
"timestamp": "2016-11-04 16:31:36.264673 ",
"event_type": "audit.delete",
"message_id": "cbcf9f2c-7c53-4b4d-91ec-db49cca024b6"
}

View File

@@ -0,0 +1,70 @@
{
"priority": "INFO",
"payload": {
"watcher_object.data": {
"audit_type": "ONESHOT",
"parameters": {
"para2": "hello",
"para1": 3.2
},
"state": "ONGOING",
"updated_at": null,
"deleted_at": null,
"fault": null,
"goal": {
"watcher_object.data": {
"uuid": "bc830f84-8ae3-4fc6-8bc6-e3dd15e8b49a",
"name": "dummy",
"updated_at": null,
"deleted_at": null,
"efficacy_specification": [],
"created_at": "2016-11-04T16:25:35Z",
"display_name": "Dummy goal"
},
"watcher_object.name": "GoalPayload",
"watcher_object.version": "1.0",
"watcher_object.namespace": "watcher"
},
"interval": null,
"scope": [],
"strategy": {
"watcher_object.data": {
"parameters_spec": {
"properties": {
"para2": {
"type": "string",
"default": "hello",
"description": "string parameter example"
},
"para1": {
"description": "number parameter example",
"maximum": 10.2,
"type": "number",
"default": 3.2,
"minimum": 1.0
}
}
},
"name": "dummy",
"uuid": "75234dfe-87e3-4f11-a0e0-3c3305d86a39",
"updated_at": null,
"deleted_at": null,
"created_at": "2016-11-04T16:25:35Z",
"display_name": "Dummy strategy"
},
"watcher_object.name": "StrategyPayload",
"watcher_object.version": "1.0",
"watcher_object.namespace": "watcher"
},
"created_at": "2016-11-04T16:29:20Z",
"uuid": "4a97b9dd-2023-43dc-b713-815bdd94d4d6"
},
"watcher_object.name": "AuditActionPayload",
"watcher_object.version": "1.0",
"watcher_object.namespace": "watcher"
},
"publisher_id": "infra-optim:localhost",
"timestamp": "2016-11-04 16:31:36.264673 ",
"event_type": "audit.planner.end",
"message_id": "cbcf9f2c-7c53-4b4d-91ec-db49cca024b6"
}

View File

@@ -0,0 +1,80 @@
{
"priority": "ERROR",
"payload": {
"watcher_object.data": {
"audit_type": "ONESHOT",
"parameters": {
"para2": "hello",
"para1": 3.2
},
"state": "ONGOING",
"updated_at": null,
"deleted_at": null,
"fault": {
"watcher_object.data": {
"exception": "WatcherException",
"exception_message": "TEST",
"function_name": "test_send_audit_action_with_error",
"module_name": "watcher.tests.notifications.test_audit_notification"
},
"watcher_object.name": "ExceptionPayload",
"watcher_object.namespace": "watcher",
"watcher_object.version": "1.0"
},
"goal": {
"watcher_object.data": {
"uuid": "bc830f84-8ae3-4fc6-8bc6-e3dd15e8b49a",
"name": "dummy",
"updated_at": null,
"deleted_at": null,
"efficacy_specification": [],
"created_at": "2016-11-04T16:25:35Z",
"display_name": "Dummy goal"
},
"watcher_object.name": "GoalPayload",
"watcher_object.version": "1.0",
"watcher_object.namespace": "watcher"
},
"interval": null,
"scope": [],
"strategy": {
"watcher_object.data": {
"parameters_spec": {
"properties": {
"para2": {
"type": "string",
"default": "hello",
"description": "string parameter example"
},
"para1": {
"description": "number parameter example",
"maximum": 10.2,
"type": "number",
"default": 3.2,
"minimum": 1.0
}
}
},
"name": "dummy",
"uuid": "75234dfe-87e3-4f11-a0e0-3c3305d86a39",
"updated_at": null,
"deleted_at": null,
"created_at": "2016-11-04T16:25:35Z",
"display_name": "Dummy strategy"
},
"watcher_object.name": "StrategyPayload",
"watcher_object.version": "1.0",
"watcher_object.namespace": "watcher"
},
"created_at": "2016-11-04T16:29:20Z",
"uuid": "4a97b9dd-2023-43dc-b713-815bdd94d4d6"
},
"watcher_object.name": "AuditActionPayload",
"watcher_object.version": "1.0",
"watcher_object.namespace": "watcher"
},
"publisher_id": "infra-optim:localhost",
"timestamp": "2016-11-04 16:31:36.264673 ",
"event_type": "audit.planner.error",
"message_id": "cbcf9f2c-7c53-4b4d-91ec-db49cca024b6"
}

View File

@@ -0,0 +1,70 @@
{
"priority": "INFO",
"payload": {
"watcher_object.data": {
"audit_type": "ONESHOT",
"parameters": {
"para2": "hello",
"para1": 3.2
},
"state": "ONGOING",
"updated_at": null,
"deleted_at": null,
"fault": null,
"goal": {
"watcher_object.data": {
"uuid": "bc830f84-8ae3-4fc6-8bc6-e3dd15e8b49a",
"name": "dummy",
"updated_at": null,
"deleted_at": null,
"efficacy_specification": [],
"created_at": "2016-11-04T16:25:35Z",
"display_name": "Dummy goal"
},
"watcher_object.name": "GoalPayload",
"watcher_object.version": "1.0",
"watcher_object.namespace": "watcher"
},
"interval": null,
"scope": [],
"strategy": {
"watcher_object.data": {
"parameters_spec": {
"properties": {
"para2": {
"type": "string",
"default": "hello",
"description": "string parameter example"
},
"para1": {
"description": "number parameter example",
"maximum": 10.2,
"type": "number",
"default": 3.2,
"minimum": 1.0
}
}
},
"name": "dummy",
"uuid": "75234dfe-87e3-4f11-a0e0-3c3305d86a39",
"updated_at": null,
"deleted_at": null,
"created_at": "2016-11-04T16:25:35Z",
"display_name": "Dummy strategy"
},
"watcher_object.name": "StrategyPayload",
"watcher_object.version": "1.0",
"watcher_object.namespace": "watcher"
},
"created_at": "2016-11-04T16:29:20Z",
"uuid": "4a97b9dd-2023-43dc-b713-815bdd94d4d6"
},
"watcher_object.name": "AuditActionPayload",
"watcher_object.version": "1.0",
"watcher_object.namespace": "watcher"
},
"publisher_id": "infra-optim:localhost",
"timestamp": "2016-11-04 16:31:36.264673 ",
"event_type": "audit.planner.start",
"message_id": "cbcf9f2c-7c53-4b4d-91ec-db49cca024b6"
}

View File

@@ -0,0 +1,70 @@
{
"priority": "INFO",
"payload": {
"watcher_object.data": {
"audit_type": "ONESHOT",
"parameters": {
"para2": "hello",
"para1": 3.2
},
"state": "ONGOING",
"updated_at": null,
"deleted_at": null,
"fault": null,
"goal": {
"watcher_object.data": {
"uuid": "bc830f84-8ae3-4fc6-8bc6-e3dd15e8b49a",
"name": "dummy",
"updated_at": null,
"deleted_at": null,
"efficacy_specification": [],
"created_at": "2016-11-04T16:25:35Z",
"display_name": "Dummy goal"
},
"watcher_object.name": "GoalPayload",
"watcher_object.version": "1.0",
"watcher_object.namespace": "watcher"
},
"interval": null,
"scope": [],
"strategy": {
"watcher_object.data": {
"parameters_spec": {
"properties": {
"para2": {
"type": "string",
"default": "hello",
"description": "string parameter example"
},
"para1": {
"description": "number parameter example",
"maximum": 10.2,
"type": "number",
"default": 3.2,
"minimum": 1.0
}
}
},
"name": "dummy",
"uuid": "75234dfe-87e3-4f11-a0e0-3c3305d86a39",
"updated_at": null,
"deleted_at": null,
"created_at": "2016-11-04T16:25:35Z",
"display_name": "Dummy strategy"
},
"watcher_object.name": "StrategyPayload",
"watcher_object.version": "1.0",
"watcher_object.namespace": "watcher"
},
"created_at": "2016-11-04T16:29:20Z",
"uuid": "4a97b9dd-2023-43dc-b713-815bdd94d4d6"
},
"watcher_object.name": "AuditActionPayload",
"watcher_object.version": "1.0",
"watcher_object.namespace": "watcher"
},
"publisher_id": "infra-optim:localhost",
"timestamp": "2016-11-04 16:31:36.264673 ",
"event_type": "audit.strategy.end",
"message_id": "cbcf9f2c-7c53-4b4d-91ec-db49cca024b6"
}

View File

@@ -0,0 +1,80 @@
{
"priority": "ERROR",
"payload": {
"watcher_object.data": {
"audit_type": "ONESHOT",
"parameters": {
"para2": "hello",
"para1": 3.2
},
"state": "ONGOING",
"updated_at": null,
"deleted_at": null,
"fault": {
"watcher_object.data": {
"exception": "WatcherException",
"exception_message": "TEST",
"function_name": "test_send_audit_action_with_error",
"module_name": "watcher.tests.notifications.test_audit_notification"
},
"watcher_object.name": "ExceptionPayload",
"watcher_object.namespace": "watcher",
"watcher_object.version": "1.0"
},
"goal": {
"watcher_object.data": {
"uuid": "bc830f84-8ae3-4fc6-8bc6-e3dd15e8b49a",
"name": "dummy",
"updated_at": null,
"deleted_at": null,
"efficacy_specification": [],
"created_at": "2016-11-04T16:25:35Z",
"display_name": "Dummy goal"
},
"watcher_object.name": "GoalPayload",
"watcher_object.version": "1.0",
"watcher_object.namespace": "watcher"
},
"interval": null,
"scope": [],
"strategy": {
"watcher_object.data": {
"parameters_spec": {
"properties": {
"para2": {
"type": "string",
"default": "hello",
"description": "string parameter example"
},
"para1": {
"description": "number parameter example",
"maximum": 10.2,
"type": "number",
"default": 3.2,
"minimum": 1.0
}
}
},
"name": "dummy",
"uuid": "75234dfe-87e3-4f11-a0e0-3c3305d86a39",
"updated_at": null,
"deleted_at": null,
"created_at": "2016-11-04T16:25:35Z",
"display_name": "Dummy strategy"
},
"watcher_object.name": "StrategyPayload",
"watcher_object.version": "1.0",
"watcher_object.namespace": "watcher"
},
"created_at": "2016-11-04T16:29:20Z",
"uuid": "4a97b9dd-2023-43dc-b713-815bdd94d4d6"
},
"watcher_object.name": "AuditActionPayload",
"watcher_object.version": "1.0",
"watcher_object.namespace": "watcher"
},
"publisher_id": "infra-optim:localhost",
"timestamp": "2016-11-04 16:31:36.264673 ",
"event_type": "audit.strategy.error",
"message_id": "cbcf9f2c-7c53-4b4d-91ec-db49cca024b6"
}

View File

@@ -0,0 +1,70 @@
{
"priority": "INFO",
"payload": {
"watcher_object.data": {
"audit_type": "ONESHOT",
"parameters": {
"para2": "hello",
"para1": 3.2
},
"state": "ONGOING",
"updated_at": null,
"deleted_at": null,
"fault": null,
"goal": {
"watcher_object.data": {
"uuid": "bc830f84-8ae3-4fc6-8bc6-e3dd15e8b49a",
"name": "dummy",
"updated_at": null,
"deleted_at": null,
"efficacy_specification": [],
"created_at": "2016-11-04T16:25:35Z",
"display_name": "Dummy goal"
},
"watcher_object.name": "GoalPayload",
"watcher_object.version": "1.0",
"watcher_object.namespace": "watcher"
},
"interval": null,
"scope": [],
"strategy": {
"watcher_object.data": {
"parameters_spec": {
"properties": {
"para2": {
"type": "string",
"default": "hello",
"description": "string parameter example"
},
"para1": {
"description": "number parameter example",
"maximum": 10.2,
"type": "number",
"default": 3.2,
"minimum": 1.0
}
}
},
"name": "dummy",
"uuid": "75234dfe-87e3-4f11-a0e0-3c3305d86a39",
"updated_at": null,
"deleted_at": null,
"created_at": "2016-11-04T16:25:35Z",
"display_name": "Dummy strategy"
},
"watcher_object.name": "StrategyPayload",
"watcher_object.version": "1.0",
"watcher_object.namespace": "watcher"
},
"created_at": "2016-11-04T16:29:20Z",
"uuid": "4a97b9dd-2023-43dc-b713-815bdd94d4d6"
},
"watcher_object.name": "AuditActionPayload",
"watcher_object.version": "1.0",
"watcher_object.namespace": "watcher"
},
"publisher_id": "infra-optim:localhost",
"timestamp": "2016-11-04 16:31:36.264673 ",
"event_type": "audit.strategy.start",
"message_id": "cbcf9f2c-7c53-4b4d-91ec-db49cca024b6"
}

View File

@@ -0,0 +1,78 @@
{
"publisher_id": "infra-optim:localhost",
"timestamp": "2016-11-04 16:51:38.722986 ",
"payload": {
"watcher_object.name": "AuditUpdatePayload",
"watcher_object.data": {
"strategy": {
"watcher_object.name": "StrategyPayload",
"watcher_object.data": {
"name": "dummy",
"parameters_spec": {
"properties": {
"para2": {
"default": "hello",
"type": "string",
"description": "string parameter example"
},
"para1": {
"maximum": 10.2,
"default": 3.2,
"minimum": 1.0,
"description": "number parameter example",
"type": "number"
}
}
},
"updated_at": null,
"display_name": "Dummy strategy",
"deleted_at": null,
"uuid": "75234dfe-87e3-4f11-a0e0-3c3305d86a39",
"created_at": "2016-11-04T16:25:35Z"
},
"watcher_object.namespace": "watcher",
"watcher_object.version": "1.0"
},
"scope": [],
"created_at": "2016-11-04T16:51:21Z",
"uuid": "f1e0d912-afd9-4bf2-91ef-c99cd08cc1ef",
"goal": {
"watcher_object.name": "GoalPayload",
"watcher_object.data": {
"efficacy_specification": [],
"updated_at": null,
"name": "dummy",
"display_name": "Dummy goal",
"deleted_at": null,
"uuid": "bc830f84-8ae3-4fc6-8bc6-e3dd15e8b49a",
"created_at": "2016-11-04T16:25:35Z"
},
"watcher_object.namespace": "watcher",
"watcher_object.version": "1.0"
},
"parameters": {
"para2": "hello",
"para1": 3.2
},
"deleted_at": null,
"state_update": {
"watcher_object.name": "AuditStateUpdatePayload",
"watcher_object.data": {
"state": "ONGOING",
"old_state": "PENDING"
},
"watcher_object.namespace": "watcher",
"watcher_object.version": "1.0"
},
"interval": null,
"updated_at": null,
"state": "ONGOING",
"audit_type": "ONESHOT"
},
"watcher_object.namespace": "watcher",
"watcher_object.version": "1.0"
},
"priority": "INFO",
"event_type": "audit.update",
"message_id": "697fdf55-7252-4b6c-a2c2-5b9e85f6342c"
}

View File

@@ -0,0 +1,16 @@
{
"event_type": "infra-optim.exception",
"payload": {
"watcher_object.data": {
"exception": "NoAvailableStrategyForGoal",
"exception_message": "No strategy could be found to achieve the server_consolidation goal.",
"function_name": "_aggregate_create_in_db",
"module_name": "watcher.objects.aggregate"
},
"watcher_object.name": "ExceptionPayload",
"watcher_object.namespace": "watcher",
"watcher_object.version": "1.0"
},
"priority": "ERROR",
"publisher_id": "watcher-api:fake-mini"
}

View File

@@ -139,7 +139,7 @@ The Watcher Dashboard can be used to interact with the Watcher system through
Horizon in order to control it or to know its current status.
Please, read `the detailed documentation about Watcher Dashboard
<https://factory.b-com.com/www/watcher/doc/watcher-dashboard/>`_.
<http://docs.openstack.org/developer/watcher-dashboard/>`_.
.. _archi_watcher_database_definition:
@@ -150,11 +150,14 @@ This database stores all the Watcher domain objects which can be requested
by the :ref:`Watcher API <archi_watcher_api_definition>` or the
:ref:`Watcher CLI <archi_watcher_cli_definition>`:
- :ref:`Goals <goal_definition>`
- :ref:`Strategies <strategy_definition>`
- :ref:`Audit templates <audit_template_definition>`
- :ref:`Audits <audit_definition>`
- :ref:`Action plans <action_plan_definition>`
- :ref:`Efficacy indicators <efficacy_indicator_definition>` via the Action
Plan API.
- :ref:`Actions <action_definition>`
- :ref:`Goals <goal_definition>`
The Watcher domain being here "*optimization of some resources provided by an
OpenStack system*".
@@ -168,37 +171,47 @@ This component is responsible for computing a set of potential optimization
:ref:`Actions <action_definition>` in order to fulfill
the :ref:`Goal <goal_definition>` of an :ref:`Audit <audit_definition>`.
It first reads the parameters of the :ref:`Audit <audit_definition>` from the
associated :ref:`Audit Template <audit_template_definition>` and knows the
:ref:`Goal <goal_definition>` to achieve.
It first reads the parameters of the :ref:`Audit <audit_definition>` to know
the :ref:`Goal <goal_definition>` to achieve.
It then selects the most appropriate :ref:`Strategy <strategy_definition>`
depending on how Watcher was configured for this :ref:`Goal <goal_definition>`.
Unless specified, it then selects the most appropriate :ref:`strategy
<strategy_definition>` from the list of available strategies achieving this
goal.
The :ref:`Strategy <strategy_definition>` is then dynamically loaded (via
`stevedore <https://github.com/openstack/stevedore/>`_). The
:ref:`Watcher Decision Engine <watcher_decision_engine_definition>` calls the
**execute()** method of the :ref:`Strategy <strategy_definition>` class which
generates a solution composed of a set of :ref:`Actions <action_definition>`.
`stevedore <http://docs.openstack.org/developer/stevedore/>`_). The
:ref:`Watcher Decision Engine <watcher_decision_engine_definition>` executes
the strategy.
In order to compute the potential :ref:`Solution <solution_definition>` for the
Audit, the :ref:`Strategy <strategy_definition>` relies on different sets of
data:
- :ref:`Cluster data models <cluster_data_model_definition>` that are
periodically synchronized through pluggable cluster data model collectors.
These models contain the current state of various
:ref:`Managed resources <managed_resource_definition>` (e.g., the data stored
in the Nova database). These models gives a strategy the ability to reason on
the current state of a given :ref:`cluster <cluster_definition>`.
- The data stored in the :ref:`Cluster History Database
<cluster_history_db_definition>` which provides information about the past of
the :ref:`Cluster <cluster_definition>`.
Here below is a sequence diagram showing how the Decision Engine builds and
maintains the :ref:`cluster data models <cluster_data_model_definition>` that
are used by the strategies.
.. image:: ./images/sequence_architecture_cdmc_sync.png
:width: 100%
The execution of a strategy then yields a solution composed of a set of
:ref:`Actions <action_definition>` as well as a set of :ref:`efficacy
indicators <efficacy_indicator_definition>`.
These :ref:`Actions <action_definition>` are scheduled in time by the
:ref:`Watcher Planner <watcher_planner_definition>` (i.e., it generates an
:ref:`Action Plan <action_plan_definition>`).
In order to compute the potential :ref:`Solution <solution_definition>` for the
Audit, the :ref:`Strategy <strategy_definition>` relies on two sets of data:
- the current state of the
:ref:`Managed resources <managed_resource_definition>`
(e.g., the data stored in the Nova database)
- the data stored in the
:ref:`Cluster History Database <cluster_history_db_definition>`
which provides information about the past of the
:ref:`Cluster <cluster_definition>`
So far, only one :ref:`Strategy <strategy_definition>` can be associated to a
given :ref:`Goal <goal_definition>` via the main Watcher configuration file.
.. _data_model:
Data model
@@ -211,6 +224,12 @@ view (Goals, Audits, Action Plans, ...):
.. image:: ./images/functional_data_model.svg
:width: 100%
Here below is a diagram representing the main objects in Watcher from a
database perspective:
.. image:: ./images/watcher_db_schema_diagram.png
.. _sequence_diagrams:
Sequence diagrams
@@ -230,13 +249,15 @@ following parameters:
- A name
- A goal to achieve
- An optional strategy
.. image:: ./images/sequence_create_audit_template.png
:width: 100%
The `Watcher API`_ just makes sure that the goal exists (i.e. it is declared
in the Watcher configuration file) and stores a new audit template in the
:ref:`Watcher Database <watcher_database_definition>`.
The `Watcher API`_ makes sure that both the specified goal (mandatory) and
its associated strategy (optional) are registered inside the :ref:`Watcher
Database <watcher_database_definition>` before storing a new audit template in
the :ref:`Watcher Database <watcher_database_definition>`.
.. _sequence_diagrams_create_and_launch_audit:
@@ -250,6 +271,13 @@ previously created :ref:`Audit template <audit_template_definition>`:
.. image:: ./images/sequence_create_and_launch_audit.png
:width: 100%
The :ref:`Administrator <administrator_definition>` also can specify type of
Audit and interval (in case of CONTINUOUS type). There is two types of Audit:
ONESHOT and CONTINUOUS. Oneshot Audit is launched once and if it succeeded
executed new action plan list will be provided. Continuous Audit creates
action plans with specified interval (in seconds); if action plan
has been created, all previous action plans get CANCELLED state.
A message is sent on the :ref:`AMQP bus <amqp_bus_definition>` which triggers
the Audit in the
:ref:`Watcher Decision Engine <watcher_decision_engine_definition>`:
@@ -260,18 +288,17 @@ the Audit in the
The :ref:`Watcher Decision Engine <watcher_decision_engine_definition>` reads
the Audit parameters from the
:ref:`Watcher Database <watcher_database_definition>`. It instantiates the
appropriate :ref:`Strategy <strategy_definition>` (using entry points)
associated to the :ref:`Goal <goal_definition>` of the
:ref:`Audit <audit_definition>` (it uses the information of the Watcher
configuration file to find the mapping between the
:ref:`Goal <goal_definition>` and the :ref:`Strategy <strategy_definition>`
python class).
appropriate :ref:`strategy <strategy_definition>` (using entry points)
given both the :ref:`goal <goal_definition>` and the strategy associated to the
parent :ref:`audit template <audit_template_definition>` of the :ref:`audit
<audit_definition>`. If no strategy is associated to the audit template, the
strategy is dynamically selected by the Decision Engine.
The :ref:`Watcher Decision Engine <watcher_decision_engine_definition>` also
builds the :ref:`Cluster Data Model <cluster_data_model_definition>`. This
data model is needed by the :ref:`Strategy <strategy_definition>` to know the
current state and topology of the audited
:ref:`Openstack cluster <cluster_definition>`.
:ref:`OpenStack cluster <cluster_definition>`.
The :ref:`Watcher Decision Engine <watcher_decision_engine_definition>` calls
the **execute()** method of the instantiated
@@ -289,9 +316,11 @@ This method finds an appropriate scheduling of
:ref:`Actions <action_definition>` taking into account some scheduling rules
(such as priorities between actions).
It generates a new :ref:`Action Plan <action_plan_definition>` with status
**RECOMMENDED** and saves it into the
:ref:`Watcher Database <watcher_database_definition>`. The saved action plan is
now a scheduled flow of actions.
**RECOMMENDED** and saves it into the :ref:`Watcher Database
<watcher_database_definition>`. The saved action plan is now a scheduled flow
of actions to which a global efficacy is associated alongside a number of
:ref:`Efficacy Indicators <efficacy_indicator_definition>` as specified by the
related :ref:`goal <goal_definition>`.
If every step executed successfully, the
:ref:`Watcher Decision Engine <watcher_decision_engine_definition>` updates
@@ -300,6 +329,11 @@ the current status of the Audit to **SUCCEEDED** in the
on the bus to inform other components that the :ref:`Audit <audit_definition>`
was successful.
This internal workflow the Decision Engine follows to conduct an audit can be
seen in the sequence diagram here below:
.. image:: ./images/sequence_from_audit_execution_to_actionplan_creation.png
:width: 100%
.. _sequence_diagrams_launch_action_plan:
@@ -361,6 +395,28 @@ State Machine diagrams
Audit State Machine
-------------------
An :ref:`Audit <audit_definition>` has a life-cycle and its current state may
be one of the following:
- **PENDING** : a request for an :ref:`Audit <audit_definition>` has been
submitted (either manually by the
:ref:`Administrator <administrator_definition>` or automatically via some
event handling mechanism) and is in the queue for being processed by the
:ref:`Watcher Decision Engine <watcher_decision_engine_definition>`
- **ONGOING** : the :ref:`Audit <audit_definition>` is currently being
processed by the
:ref:`Watcher Decision Engine <watcher_decision_engine_definition>`
- **SUCCEEDED** : the :ref:`Audit <audit_definition>` has been executed
successfully and at least one solution was found
- **FAILED** : an error occurred while executing the
:ref:`Audit <audit_definition>`
- **DELETED** : the :ref:`Audit <audit_definition>` is still stored in the
:ref:`Watcher database <watcher_database_definition>` but is not returned
any more through the Watcher APIs.
- **CANCELLED** : the :ref:`Audit <audit_definition>` was in **PENDING** or
**ONGOING** state and was cancelled by the
:ref:`Administrator <administrator_definition>`
The following diagram shows the different possible states of an
:ref:`Audit <audit_definition>` and what event makes the state change to a new
value:
@@ -373,6 +429,31 @@ value:
Action Plan State Machine
-------------------------
An :ref:`Action Plan <action_plan_definition>` has a life-cycle and its current
state may be one of the following:
- **RECOMMENDED** : the :ref:`Action Plan <action_plan_definition>` is waiting
for a validation from the :ref:`Administrator <administrator_definition>`
- **PENDING** : a request for an :ref:`Action Plan <action_plan_definition>`
has been submitted (due to an
:ref:`Administrator <administrator_definition>` executing an
:ref:`Audit <audit_definition>`) and is in the queue for
being processed by the :ref:`Watcher Applier <watcher_applier_definition>`
- **ONGOING** : the :ref:`Action Plan <action_plan_definition>` is currently
being processed by the :ref:`Watcher Applier <watcher_applier_definition>`
- **SUCCEEDED** : the :ref:`Action Plan <action_plan_definition>` has been
executed successfully (i.e. all :ref:`Actions <action_definition>` that it
contains have been executed successfully)
- **FAILED** : an error occurred while executing the
:ref:`Action Plan <action_plan_definition>`
- **DELETED** : the :ref:`Action Plan <action_plan_definition>` is still
stored in the :ref:`Watcher database <watcher_database_definition>` but is
not returned any more through the Watcher APIs.
- **CANCELLED** : the :ref:`Action Plan <action_plan_definition>` was in
**RECOMMENDED**, **PENDING** or **ONGOING** state and was cancelled by the
:ref:`Administrator <administrator_definition>`
The following diagram shows the different possible states of an
:ref:`Action Plan <action_plan_definition>` and what event makes the state
change to a new value:

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# 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
@@ -11,7 +10,21 @@
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import sys
from watcher import version as watcher_version
from watcher import objects
objects.register_all()
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
sys.path.insert(0, os.path.abspath('../../'))
sys.path.insert(0, os.path.abspath('../'))
sys.path.insert(0, os.path.abspath('./'))
# -- General configuration ----------------------------------------------------
@@ -19,13 +32,15 @@ from watcher import version as watcher_version
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = [
'oslo_config.sphinxconfiggen',
'oslosphinx',
'sphinx.ext.autodoc',
'sphinx.ext.viewcode',
'sphinxcontrib.httpdomain',
'sphinxcontrib.pecanwsme.rest',
'stevedore.sphinxext',
'wsmeext.sphinxext',
'oslosphinx',
'watcher.doc',
'ext.term',
'ext.versioned_notifications',
]
wsme_protocols = ['restjson']
@@ -66,6 +81,8 @@ exclude_patterns = [
# them when scanning for input files.
'man/footer.rst',
'man/general-options.rst',
'strategies/strategy-template.rst',
'image_src/plantuml/README.rst',
]
# If true, '()' will be appended to :func: etc. cross-reference text.

View File

@@ -15,7 +15,7 @@ Service overview
================
The Watcher system is a collection of services that provides support to
optimize your IAAS plateform. The Watcher service may, depending upon
optimize your IAAS platform. The Watcher service may, depending upon
configuration, interact with several other OpenStack services. This includes:
- the OpenStack Identity service (`keystone`_) for request authentication and
@@ -37,7 +37,7 @@ The Watcher service includes the following components:
- `watcher-dashboard`_: An Horizon plugin for interacting with the Watcher
service.
Additionally, the Bare Metal service has certain external dependencies, which
Additionally, the Watcher service has certain external dependencies, which
are very similar to other OpenStack services:
- A database to store audit and action plan information and state. You can set
@@ -86,7 +86,6 @@ Configure the Identity service for the Watcher service
--tenant=KEYSTONE_SERVICE_PROJECT_NAME
$ keystone user-role-add --user=watcher \
--tenant=KEYSTONE_SERVICE_PROJECT_NAME --role=admin
$ keystone user-role-add --user=watcher --tenant=admin --role=admin
or (by using python-openstackclient 1.8.0+)
@@ -97,7 +96,6 @@ Configure the Identity service for the Watcher service
--project=KEYSTONE_SERVICE_PROJECT_NAME
$ openstack role add --project KEYSTONE_SERVICE_PROJECT_NAME \
--user watcher admin
$ openstack role add --user watcher --project admin admin
#. You must register the Watcher Service with the Identity Service so that
@@ -169,7 +167,7 @@ these following commands::
$ git clone git://git.openstack.org/openstack/watcher
$ cd watcher/
$ tox -econfig
$ tox -e genconfig
$ vi etc/watcher/watcher.conf.sample
@@ -182,8 +180,6 @@ The configuration file is organized into the following sections:
* ``[watcher_clients_auth]`` - Keystone auth configuration for clients
* ``[watcher_applier]`` - Watcher Applier module configuration
* ``[watcher_decision_engine]`` - Watcher Decision Engine module configuration
* ``[watcher_goals]`` - Goals mapping configuration
* ``[watcher_strategies]`` - Strategy configuration
* ``[oslo_messaging_rabbit]`` - Oslo Messaging RabbitMQ driver configuration
* ``[ceilometer_client]`` - Ceilometer client configuration
* ``[cinder_client]`` - Cinder client configuration
@@ -370,7 +366,7 @@ Configure Nova compute
Please check your hypervisor configuration to correctly handle
`instance migration`_.
.. _`instance migration`: http://docs.openstack.org/admin-guide-cloud/compute-configuring-migrations.html
.. _`instance migration`: http://docs.openstack.org/admin-guide/compute-live-migration-usage.html
Configure Measurements
======================
@@ -405,6 +401,35 @@ own storage driver using whatever technology you want.
For more information : https://wiki.openstack.org/wiki/Gnocchi
Configure Nova Notifications
============================
Watcher can consume notifications generated by the Nova services, in order to
build or update, in real time, its cluster data model related to computing
resources.
Nova publishes, by default, notifications on ``notifications`` AMQP queue
(configurable) and ``versioned_notifications`` AMQP queue (not
configurable). ``notifications`` queue is mainly used by ceilometer, so we can
not use it. And some events, related to nova-compute service state, are only
sent into the ``versioned_notifications`` queue.
By default, Watcher listens to AMQP queues named ``watcher_notifications``
and ``versioned_notifications``. So you have to update the Nova
configuration file on controller and compute nodes, in order
to Watcher receives Nova notifications in ``watcher_notifications`` as well.
* In the file ``/etc/nova/nova.conf``, update the section
``[oslo_messaging_notifications]``, by redefining the list of topics
into which Nova services will publish events ::
[oslo_messaging_notifications]
driver = messaging
topics = notifications,watcher_notifications
* Restart the Nova services.
Workers
=======

52
doc/source/deploy/gmr.rst Normal file
View File

@@ -0,0 +1,52 @@
..
Except where otherwise noted, this document is licensed under Creative
Commons Attribution 3.0 License. You can view the license at:
https://creativecommons.org/licenses/by/3.0/
.. _watcher_gmr:
=======================
Guru Meditation Reports
=======================
Watcher contains a mechanism whereby developers and system administrators can
generate a report about the state of a running Watcher service. This report
is called a *Guru Meditation Report* (*GMR* for short).
Generating a GMR
================
A *GMR* can be generated by sending the *USR2* signal to any Watcher process
with support (see below). The *GMR* will then be outputted as standard error
for that particular process.
For example, suppose that ``watcher-api`` has process id ``8675``, and was run
with ``2>/var/log/watcher/watcher-api-err.log``. Then, ``kill -USR2 8675``
will trigger the Guru Meditation report to be printed to
``/var/log/watcher/watcher-api-err.log``.
Structure of a GMR
==================
The *GMR* is designed to be extensible; any particular service may add its
own sections. However, the base *GMR* consists of several sections:
Package
Shows information about the package to which this process belongs, including
version informations.
Threads
Shows stack traces and thread ids for each of the threads within this
process.
Green Threads
Shows stack traces for each of the green threads within this process (green
threads don't have thread ids).
Configuration
Lists all the configuration options currently accessible via the CONF object
for the current process.
Plugins
Lists all the plugins currently accessible by the Watcher service.

View File

@@ -90,7 +90,7 @@ should be able to run the Watcher services by issuing these commands:
By default, this will show logging on the console from which it was started.
Once started, you can use the `Watcher Client`_ to play with Watcher service.
.. _`Watcher Client`: https://git.openstack.org/openstack/python-watcherclient.git
.. _`Watcher Client`: https://git.openstack.org/cgit/openstack/python-watcherclient
Installing from packages: PyPI
--------------------------------
@@ -108,3 +108,54 @@ installed on your system.
Once installed, you still need to declare Watcher as a new service into
Keystone and to configure its different modules, which you can find described
in :doc:`configuration`.
Installing from packages: Debian (experimental)
-----------------------------------------------
Experimental Debian packages are available on `Debian repositories`_. The best
way to use them is to install them into a Docker_ container.
Here is single Dockerfile snippet you can use to run your Docker container:
.. code-block:: bash
FROM debian:experimental
MAINTAINER David TARDIVEL <david.tardivel@b-com.com>
RUN apt-get update
RUN apt-get dist-upgrade -y
RUN apt-get install -y vim net-tools
RUN apt-get install -yt experimental watcher-api
CMD ["/usr/bin/watcher-api"]
Build your container from this Dockerfile:
.. code-block:: bash
$ docker build -t watcher/api .
To run your container, execute this command:
.. code-block:: bash
$ docker run -d -p 9322:9322 watcher/api
Check in your logs Watcher API is started
.. code-block:: bash
$ docker logs <container ID>
You can run similar container with Watcher Decision Engine (package
``watcher-decision-engine``) and with the Watcher Applier (package
``watcher-applier``).
.. _Docker: https://www.docker.com/
.. _`Debian repositories`: https://packages.debian.org/experimental/allpackages

View File

@@ -0,0 +1,142 @@
..
Copyright 2016 OpenStack Foundation
All Rights Reserved.
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.
Policies
========
Watcher's public API calls may be restricted to certain sets of users using a
policy configuration file. This document explains exactly how policies are
configured and what they apply to.
A policy is composed of a set of rules that are used in determining if a
particular action may be performed by the authorized tenant.
Constructing a Policy Configuration File
----------------------------------------
A policy configuration file is a simply JSON object that contain sets of
rules. Each top-level key is the name of a rule. Each rule
is a string that describes an action that may be performed in the Watcher API.
The actions that may have a rule enforced on them are:
* ``strategy:get_all``, ``strategy:detail`` - List available strategies
* ``GET /v1/strategies``
* ``GET /v1/strategies/detail``
* ``strategy:get`` - Retrieve a specific strategy entity
* ``GET /v1/strategies/<STRATEGY_UUID>``
* ``GET /v1/strategies/<STRATEGY_NAME>``
* ``goal:get_all``, ``goal:detail`` - List available goals
* ``GET /v1/goals``
* ``GET /v1/goals/detail``
* ``goal:get`` - Retrieve a specific goal entity
* ``GET /v1/goals/<GOAL_UUID>``
* ``GET /v1/goals/<GOAL_NAME>``
* ``audit_template:get_all``, ``audit_template:detail`` - List available
audit_templates
* ``GET /v1/audit_templates``
* ``GET /v1/audit_templates/detail``
* ``audit_template:get`` - Retrieve a specific audit template entity
* ``GET /v1/audit_templates/<AUDIT_TEMPLATE_UUID>``
* ``GET /v1/audit_templates/<AUDIT_TEMPLATE_NAME>``
* ``audit_template:create`` - Create an audit template entity
* ``POST /v1/audit_templates``
* ``audit_template:delete`` - Delete an audit template entity
* ``DELETE /v1/audit_templates/<AUDIT_TEMPLATE_UUID>``
* ``DELETE /v1/audit_templates/<AUDIT_TEMPLATE_NAME>``
* ``audit_template:update`` - Update an audit template entity
* ``PATCH /v1/audit_templates/<AUDIT_TEMPLATE_UUID>``
* ``PATCH /v1/audit_templates/<AUDIT_TEMPLATE_NAME>``
* ``audit:get_all``, ``audit:detail`` - List available audits
* ``GET /v1/audits``
* ``GET /v1/audits/detail``
* ``audit:get`` - Retrieve a specific audit entity
* ``GET /v1/audits/<AUDIT_UUID>``
* ``audit:create`` - Create an audit entity
* ``POST /v1/audits``
* ``audit:delete`` - Delete an audit entity
* ``DELETE /v1/audits/<AUDIT_UUID>``
* ``audit:update`` - Update an audit entity
* ``PATCH /v1/audits/<AUDIT_UUID>``
* ``action_plan:get_all``, ``action_plan:detail`` - List available action plans
* ``GET /v1/action_plans``
* ``GET /v1/action_plans/detail``
* ``action_plan:get`` - Retrieve a specific action plan entity
* ``GET /v1/action_plans/<ACTION_PLAN_UUID>``
* ``action_plan:delete`` - Delete an action plan entity
* ``DELETE /v1/action_plans/<ACTION_PLAN_UUID>``
* ``action_plan:update`` - Update an action plan entity
* ``PATCH /v1/audits/<ACTION_PLAN_UUID>``
* ``action:get_all``, ``action:detail`` - List available action
* ``GET /v1/actions``
* ``GET /v1/actions/detail``
* ``action:get`` - Retrieve a specific action plan entity
* ``GET /v1/actions/<ACTION_UUID>``
To limit an action to a particular role or roles, you list the roles like so ::
{
"audit:create": ["role:admin", "role:superuser"]
}
The above would add a rule that only allowed users that had roles of either
"admin" or "superuser" to launch an audit.

View File

@@ -11,7 +11,7 @@ Watcher User Guide
==================
See the
`architecture page <https://factory.b-com.com/www/watcher/doc/watcher/architecture.html>`_
`architecture page <http://docs.openstack.org/developer/watcher/architecture.html>`_
for an architectural overview of the different components of Watcher and how
they fit together.
@@ -32,17 +32,17 @@ This guide assumes you have a working installation of Watcher. If you get
Please refer to the `installation guide`_.
In order to use Watcher, you have to configure your credentials suitable for
watcher command-line tools.
If you need help on a specific command, you can use:
.. code:: bash
$ watcher help COMMAND
You can interact with Watcher either by using our dedicated `Watcher CLI`_
named ``watcher``, or by using the `OpenStack CLI`_ ``openstack``.
If you want to deploy Watcher in Horizon, please refer to the `Watcher Horizon
plugin installation guide`_.
.. _`installation guide`: https://factory.b-com.com/www/watcher/doc/python-watcherclient
.. _`Watcher Horizon plugin installation guide`: https://factory.b-com.com/www/watcher/doc/watcher-dashboard/deploy/installation.html
.. _`installation guide`: http://docs.openstack.org/developer/python-watcherclient
.. _`Watcher Horizon plugin installation guide`: http://docs.openstack.org/developer/watcher-dashboard/deploy/installation.html
.. _`OpenStack CLI`: http://docs.openstack.org/developer/python-openstackclient/man/openstack.html
.. _`Watcher CLI`: http://docs.openstack.org/developer/python-watcherclient/index.html
Seeing what the Watcher CLI can do ?
------------------------------------
@@ -51,23 +51,76 @@ watcher binary without options.
.. code:: bash
$ watcher
$ watcher help
or::
$ openstack help optimize
How do I run an audit of my cluster ?
-------------------------------------
First, you need to create an :ref:`audit template <audit_template_definition>`.
An :ref:`audit template <audit_template_definition>` defines an optimization
:ref:`goal <goal_definition>` to achieve (i.e. the settings of your audit).
This goal should be declared in the Watcher service configuration file
**/etc/watcher/watcher.conf**.
First, you need to find the :ref:`goal <goal_definition>` you want to achieve:
.. code:: bash
$ watcher audit-template-create my_first_audit DUMMY
$ watcher goal list
If you get "*You must provide a username via either --os-username or via
env[OS_USERNAME]*" you may have to verify your credentials.
or::
$ openstack optimize goal list
.. note::
If you get "*You must provide a username via either --os-username or via
env[OS_USERNAME]*" you may have to verify your credentials.
Then, you can create an :ref:`audit template <audit_template_definition>`.
An :ref:`audit template <audit_template_definition>` defines an optimization
:ref:`goal <goal_definition>` to achieve (i.e. the settings of your audit).
.. code:: bash
$ watcher audittemplate create my_first_audit_template <your_goal>
or::
$ openstack optimize audittemplate create my_first_audit_template <your_goal>
Although optional, you may want to actually set a specific strategy for your
audit template. If so, you may can search of its UUID or name using the
following command:
.. code:: bash
$ watcher strategy list --goal <your_goal_uuid_or_name>
or::
$ openstack optimize strategy list --goal <your_goal_uuid_or_name>
You can use the following command to check strategy details including which
parameters of which format it supports:
.. code:: bash
$ watcher strategy show <your_strategy>
or::
$ openstack optimize strategy show <your_strategy>
The command to create your audit template would then be:
.. code:: bash
$ watcher audittemplate create my_first_audit_template <your_goal> \
--strategy <your_strategy>
or::
$ openstack optimize audittemplate create my_first_audit_template <your_goal> \
--strategy <your_strategy>
Then, you can create an audit. An audit is a request for optimizing your
cluster depending on the specified :ref:`goal <goal_definition>`.
@@ -76,23 +129,50 @@ You can launch an audit on your cluster by referencing the
:ref:`audit template <audit_template_definition>` (i.e. the settings of your
audit) that you want to use.
- Get the :ref:`audit template <audit_template_definition>` UUID:
- Get the :ref:`audit template <audit_template_definition>` UUID or name:
.. code:: bash
$ watcher audit-template-list
$ watcher audittemplate list
or::
$ openstack optimize audittemplate list
- Start an audit based on this :ref:`audit template
<audit_template_definition>` settings:
.. code:: bash
$ watcher audit-create -a <your_audit_template_uuid>
$ watcher audit create -a <your_audit_template>
or::
$ openstack optimize audit create -a <your_audit_template>
If your_audit_template was created by --strategy <your_strategy>, and it
defines some parameters (command `watcher strategy show` to check parameters
format), your can append `-p` to input required parameters:
.. code:: bash
$ watcher audit create -a <your_audit_template> \
-p <your_strategy_para1>=5.5 -p <your_strategy_para2>=hi
or::
$ openstack optimize audit create -a <your_audit_template> \
-p <your_strategy_para1>=5.5 -p <your_strategy_para2>=hi
Input parameter could cause audit creation failure, when:
- no predefined strategy for audit template
- no parameters spec in predefined strategy
- input parameters don't comply with spec
Watcher service will compute an :ref:`Action Plan <action_plan_definition>`
composed of a list of potential optimization :ref:`actions <action_definition>`
(instance migration, disabling of an hypervisor, ...) according to the
(instance migration, disabling of a compute node, ...) according to the
:ref:`goal <goal_definition>` to achieve. You can see all of the goals
available in section ``[watcher_strategies]`` of the Watcher service
configuration file.
@@ -102,15 +182,22 @@ configuration file.
.. code:: bash
$ watcher action-plan-list --audit <the_audit_uuid>
$ watcher actionplan list --audit <the_audit_uuid>
or::
$ openstack optimize actionplan list --audit <the_audit_uuid>
- Have a look on the list of optimization :ref:`actions <action_definition>`
contained in this new :ref:`action plan <action_plan_definition>`:
.. code:: bash
$ watcher action-list --action-plan <the_action_plan_uuid>
$ watcher action list --action-plan <the_action_plan_uuid>
or::
$ openstack optimize action list --action-plan <the_action_plan_uuid>
Once you have learned how to create an :ref:`Action Plan
<action_plan_definition>`, it's time to go further by applying it to your
@@ -120,18 +207,30 @@ cluster:
.. code:: bash
$ watcher action-plan-start <the_action_plan_uuid>
$ watcher actionplan start <the_action_plan_uuid>
or::
$ openstack optimize actionplan start <the_action_plan_uuid>
You can follow the states of the :ref:`actions <action_definition>` by
periodically calling:
.. code:: bash
$ watcher action-list
$ watcher action list
or::
$ openstack optimize action list
You can also obtain more detailed information about a specific action:
.. code:: bash
$ watcher action-show <the_action_uuid>
$ watcher action show <the_action_uuid>
or::
$ openstack optimize action show <the_action_uuid>

View File

@@ -64,8 +64,8 @@ IRC Channel
``#openstack-watcher`` (changelog_)
Weekly Meetings
on Wednesdays at 14:00 UTC in the ``#openstack-meeting-4`` IRC
channel (`meetings logs`_)
on Wednesdays at 14:00 UTC on even weeks, 9:00 UTC on odd weeks, in the
``#openstack-meeting-4`` IRC channel (`meetings logs`_)
.. _changelog: http://eavesdrop.openstack.org/irclogs/%23openstack-watcher/
.. _meetings logs: http://eavesdrop.openstack.org/meetings/watcher/

View File

@@ -160,7 +160,7 @@ Edit `/etc/libvirt/libvirtd.conf` to make sure the following values are set::
Edit `/etc/default/libvirt-bin`::
libvirt_opts="-d -l"
libvirtd_opts="-d -l"
Restart the libvirt service::
@@ -193,6 +193,37 @@ must exist in every other compute node's stack user's authorized_keys file and
every compute node's public ECDSA key needs to be in every other compute
node's root user's known_hosts file.
Disable serial console
----------------------
Serial console needs to be disabled for live migration to work.
On both the controller and compute node, in /etc/nova/nova.conf
[serial_console]
enabled = False
Alternatively, in devstack's local.conf:
[[post-config|$NOVA_CONF]]
[serial_console]
#enabled=false
VNC server configuration
------------------------
The VNC server listening parameter needs to be set to any address so
that the server can accept connections from all of the compute nodes.
On both the controller and compute node, in /etc/nova/nova.conf
vncserver_listen = 0.0.0.0
Alternatively, in devstack's local.conf:
VNCSERVER_LISTEN=0.0.0.0
Environment final checkup
-------------------------

View File

@@ -17,7 +17,7 @@ To install Watcher from packaging, refer instead to Watcher `User
Documentation`_.
.. _`Git Repository`: http://git.openstack.org/cgit/openstack/watcher
.. _`User Documentation`: https://factory.b-com.com/www/watcher/doc/watcher/
.. _`User Documentation`: http://docs.openstack.org/developer/watcher/
Prerequisites
=============
@@ -85,6 +85,9 @@ your platform.
$ sudo yum install openssl-devel libffi-devel mysql-devel
* CentOS 7::
$ sudo yum install gcc python-devel libxml2-devel libxslt-devel mariadb-devel
PyPi Packages and VirtualEnv
----------------------------
@@ -205,7 +208,7 @@ place:
$ workon watcher
(watcher) $ watcher-db-manage --create_schema
(watcher) $ watcher-db-manage create_schema
Running Watcher services

View File

@@ -0,0 +1,13 @@
..
Except where otherwise noted, this document is licensed under Creative
Commons Attribution 3.0 License. You can view the license at:
https://creativecommons.org/licenses/by/3.0/
.. _watcher_notifications:
========================
Notifications in Watcher
========================
.. versioned_notifications::

View File

@@ -4,6 +4,8 @@
https://creativecommons.org/licenses/by/3.0/
.. _implement_action_plugin:
==================
Build a new action
==================
@@ -28,12 +30,12 @@ implement:
implement. This is the first function to be called by the
:ref:`applier <watcher_applier_definition>` before any further processing
and its role is to validate the input parameters that were provided to it.
- The :py:meth:`~.BaseAction.precondition` is called before the execution of
- The :py:meth:`~.BaseAction.pre_condition` is called before the execution of
an action. This method is a hook that can be used to perform some
initializations or to make some more advanced validation on its input
parameters. If you wish to block the execution based on this factor, you
simply have to ``raise`` an exception.
- The :py:meth:`~.BaseAction.postcondition` is called after the execution of
- The :py:meth:`~.BaseAction.post_condition` is called after the execution of
an action. As this function is called regardless of whether an action
succeeded or not, this can prove itself useful to perform cleanup
operations.
@@ -55,7 +57,7 @@ Here is an example showing how you can write a plugin called ``DummyAction``:
from watcher.applier.actions import base
class DummyAction(baseBaseAction):
class DummyAction(base.BaseAction):
@property
def schema(self):
@@ -69,32 +71,74 @@ Here is an example showing how you can write a plugin called ``DummyAction``:
# Does nothing
pass
def precondition(self):
def pre_condition(self):
# No pre-checks are done here
pass
def postcondition(self):
def post_condition(self):
# Nothing done here
pass
This implementation is the most basic one. So if you want to have more advanced
examples, have a look at the implementation of the actions already provided
by Watcher like.
To get a better understanding on how to implement a more advanced action,
have a look at the :py:class:`~watcher.applier.actions.migration.Migrate`
class.
This implementation is the most basic one. So in order to get a better
understanding on how to implement a more advanced action, have a look at the
:py:class:`~watcher.applier.actions.migration.Migrate` class.
Input validation
----------------
As you can see in the previous example, we are using `Voluptuous`_ to validate
the input parameters of an action. So if you want to learn more about how to
work with `Voluptuous`_, you can have a look at their `documentation`_ here:
work with `Voluptuous`_, you can have a look at their `documentation`_:
.. _Voluptuous: https://github.com/alecthomas/voluptuous
.. _documentation: https://github.com/alecthomas/voluptuous/blob/master/README.md
Define configuration parameters
===============================
At this point, you have a fully functional action. However, in more complex
implementation, you may want to define some configuration options so one can
tune the action to its needs. To do so, you can implement the
:py:meth:`~.Loadable.get_config_opts` class method as followed:
.. code-block:: python
from oslo_config import cfg
class DummyAction(base.BaseAction):
# [...]
def execute(self):
assert self.config.test_opt == 0
@classmethod
def get_config_opts(cls):
return super(
DummyAction, cls).get_config_opts() + [
cfg.StrOpt('test_opt', help="Demo Option.", default=0),
# Some more options ...
]
The configuration options defined within this class method will be included
within the global ``watcher.conf`` configuration file under a section named by
convention: ``{namespace}.{plugin_name}``. In our case, the ``watcher.conf``
configuration would have to be modified as followed:
.. code-block:: ini
[watcher_actions.dummy]
# Option used for testing.
test_opt = test_value
Then, the configuration options you define within this method will then be
injected in each instantiated object via the ``config`` parameter of the
:py:meth:`~.BaseAction.__init__` method.
Abstract Plugin Class
=====================
@@ -103,6 +147,7 @@ should implement:
.. autoclass:: watcher.applier.actions.base.BaseAction
:members:
:special-members: __init__
:noindex:
.. py:attribute:: schema
@@ -160,6 +205,9 @@ By doing so, your action will be saved within the Watcher Database, ready to be
processed by the planner for creating an action plan which can then be executed
by the Watcher Applier via its workflow engine.
At the last, remember to add the action into the weights in ``watcher.conf``,
otherwise you will get an error when the action be referenced in a strategy.
Scheduling of an action plugin
==============================

View File

@@ -71,8 +71,15 @@ structure that looks like this::
│   └── test_thirdparty.py
└── tox.ini
**Note:** You should add `python-watcher`_ as a dependency in the
requirements.txt file::
# Watcher-specific requirements
python-watcher
.. _cookiecutter: https://github.com/audreyr/cookiecutter
.. _OpenStack cookiecutter: https://github.com/openstack-dev/cookiecutter
.. _python-watcher: https://pypi.python.org/pypi/python-watcher
Implementing a plugin for Watcher
=================================
@@ -81,10 +88,13 @@ Now that the project skeleton has been created, you can start the
implementation of your plugin. As of now, you can implement the following
plugins for Watcher:
- A :ref:`goal plugin <implement_goal_plugin>`
- A :ref:`strategy plugin <implement_strategy_plugin>`
- An :ref:`action plugin <implement_action_plugin>`
- A :ref:`planner plugin <implement_planner_plugin>`
- An :ref:`action plugin <implement_strategy_plugin>`
- A :ref:`workflow engine plugin <implement_workflow_engine_plugin>`
- A workflow engine plugin
- A :ref:`cluster data model collector plugin
<implement_cluster_data_model_collector_plugin>`
If you want to learn more on how to implement them, you can refer to their
dedicated documentation.

View File

@@ -0,0 +1,272 @@
..
Except where otherwise noted, this document is licensed under Creative
Commons Attribution 3.0 License. You can view the license at:
https://creativecommons.org/licenses/by/3.0/
.. _implement_cluster_data_model_collector_plugin:
========================================
Build a new cluster data model collector
========================================
Watcher Decision Engine has an external cluster data model (CDM) plugin
interface which gives anyone the ability to integrate an external cluster data
model collector (CDMC) in order to extend the initial set of cluster data model
collectors Watcher provides.
This section gives some guidelines on how to implement and integrate custom
cluster data model collectors within Watcher.
Creating a new plugin
=====================
In order to create a new cluster data model collector, you have to:
- Extend the :py:class:`~.base.BaseClusterDataModelCollector` class.
- Implement its :py:meth:`~.BaseClusterDataModelCollector.execute` abstract
method to return your entire cluster data model that this method should
build.
- Implement its :py:meth:`~.Goal.notification_endpoints` abstract property to
return the list of all the :py:class:`~.base.NotificationEndpoint` instances
that will be responsible for handling incoming notifications in order to
incrementally update your cluster data model.
First of all, you have to extend the :class:`~.BaseClusterDataModelCollector`
base class which defines the :py:meth:`~.BaseClusterDataModelCollector.execute`
abstract method you will have to implement. This method is responsible for
building an entire cluster data model.
Here is an example showing how you can write a plugin called
``DummyClusterDataModelCollector``:
.. code-block:: python
# Filepath = <PROJECT_DIR>/thirdparty/dummy.py
# Import path = thirdparty.dummy
from watcher.decision_engine.model import model_root
from watcher.decision_engine.model.collector import base
class DummyClusterDataModelCollector(base.BaseClusterDataModelCollector):
def execute(self):
model = model_root.ModelRoot()
# Do something here...
return model
@property
def notification_endpoints(self):
return []
This implementation is the most basic one. So in order to get a better
understanding on how to implement a more advanced cluster data model collector,
have a look at the :py:class:`~.NovaClusterDataModelCollector` class.
Define a custom model
=====================
As you may have noticed in the above example, we are reusing an existing model
provided by Watcher. However, this model can be easily customized by
implementing a new class that would implement the :py:class:`~.Model` abstract
base class. Here below is simple example on how to proceed in implementing a
custom Model:
.. code-block:: python
# Filepath = <PROJECT_DIR>/thirdparty/dummy.py
# Import path = thirdparty.dummy
from watcher.decision_engine.model import base as modelbase
from watcher.decision_engine.model.collector import base
class MyModel(modelbase.Model):
def to_string(self):
return 'MyModel'
class DummyClusterDataModelCollector(base.BaseClusterDataModelCollector):
def execute(self):
model = MyModel()
# Do something here...
return model
@property
def notification_endpoints(self):
return []
Here below is the abstract ``Model`` class that every single cluster data model
should implement:
.. autoclass:: watcher.decision_engine.model.base.Model
:members:
:special-members: __init__
:noindex:
Define configuration parameters
===============================
At this point, you have a fully functional cluster data model collector.
By default, cluster data model collectors define a ``period`` option (see
:py:meth:`~.BaseClusterDataModelCollector.get_config_opts`) that corresponds
to the interval of time between each synchronization of the in-memory model.
However, in more complex implementation, you may want to define some
configuration options so one can tune the cluster data model collector to your
needs. To do so, you can implement the :py:meth:`~.Loadable.get_config_opts`
class method as followed:
.. code-block:: python
from oslo_config import cfg
from watcher.decision_engine.model import model_root
from watcher.decision_engine.model.collector import base
class DummyClusterDataModelCollector(base.BaseClusterDataModelCollector):
def execute(self):
model = model_root.ModelRoot()
# Do something here...
return model
@property
def notification_endpoints(self):
return []
@classmethod
def get_config_opts(cls):
return super(
DummyClusterDataModelCollector, cls).get_config_opts() + [
cfg.StrOpt('test_opt', help="Demo Option.", default=0),
# Some more options ...
]
The configuration options defined within this class method will be included
within the global ``watcher.conf`` configuration file under a section named by
convention: ``{namespace}.{plugin_name}`` (see section :ref:`Register a new
entry point <register_new_cdmc_entrypoint>`). The namespace for CDMC plugins is
``watcher_cluster_data_model_collectors``, so in our case, the ``watcher.conf``
configuration would have to be modified as followed:
.. code-block:: ini
[watcher_cluster_data_model_collectors.dummy]
# Option used for testing.
test_opt = test_value
Then, the configuration options you define within this method will then be
injected in each instantiated object via the ``config`` parameter of the
:py:meth:`~.BaseClusterDataModelCollector.__init__` method.
Abstract Plugin Class
=====================
Here below is the abstract ``BaseClusterDataModelCollector`` class that every
single cluster data model collector should implement:
.. autoclass:: watcher.decision_engine.model.collector.base.BaseClusterDataModelCollector
:members:
:special-members: __init__
:noindex:
.. _register_new_cdmc_entrypoint:
Register a new entry point
==========================
In order for the Watcher Decision Engine to load your new cluster data model
collector, the latter must be registered as a named entry point under the
``watcher_cluster_data_model_collectors`` entry point namespace of your
``setup.py`` file. If you are using pbr_, this entry point should be placed in
your ``setup.cfg`` file.
The name you give to your entry point has to be unique.
Here below is how to register ``DummyClusterDataModelCollector`` using pbr_:
.. code-block:: ini
[entry_points]
watcher_cluster_data_model_collectors =
dummy = thirdparty.dummy:DummyClusterDataModelCollector
.. _pbr: http://docs.openstack.org/developer/pbr/
Add new notification endpoints
==============================
At this point, you have a fully functional cluster data model collector.
However, this CDMC is only refreshed periodically via a background scheduler.
As you may sometimes execute a strategy with a stale CDM due to a high activity
on your infrastructure, you can define some notification endpoints that will be
responsible for incrementally updating the CDM based on notifications emitted
by other services such as Nova. To do so, you can implement and register a new
``DummyEndpoint`` notification endpoint regarding a ``dummy`` event as shown
below:
.. code-block:: python
from watcher.decision_engine.model import model_root
from watcher.decision_engine.model.collector import base
class DummyNotification(base.NotificationEndpoint):
@property
def filter_rule(self):
return filtering.NotificationFilter(
publisher_id=r'.*',
event_type=r'^dummy$',
)
def info(self, ctxt, publisher_id, event_type, payload, metadata):
# Do some CDM modifications here...
pass
class DummyClusterDataModelCollector(base.BaseClusterDataModelCollector):
def execute(self):
model = model_root.ModelRoot()
# Do something here...
return model
@property
def notification_endpoints(self):
return [DummyNotification(self)]
Note that if the event you are trying to listen to is published by a new
service, you may have to also add a new topic Watcher will have to subscribe to
in the ``notification_topics`` option of the ``[watcher_decision_engine]``
section.
Using cluster data model collector plugins
==========================================
The Watcher Decision Engine service will automatically discover any installed
plugins when it is restarted. If a Python package containing a custom plugin is
installed within the same environment as Watcher, Watcher will automatically
make that plugin available for use.
At this point, you can use your new cluster data model plugin in your
:ref:`strategy plugin <implement_strategy_plugin>` by using the
:py:attr:`~.BaseStrategy.collector_manager` property as followed:
.. code-block:: python
# [...]
dummy_collector = self.collector_manager.get_cluster_model_collector(
"dummy") # "dummy" is the name of the entry point we declared earlier
dummy_model = dummy_collector.get_latest_cluster_data_model()
# Do some stuff with this model

View File

@@ -0,0 +1,215 @@
..
Except where otherwise noted, this document is licensed under Creative
Commons Attribution 3.0 License. You can view the license at:
https://creativecommons.org/licenses/by/3.0/
.. _implement_goal_plugin:
================
Build a new goal
================
Watcher Decision Engine has an external :ref:`goal <goal_definition>`
plugin interface which gives anyone the ability to integrate an external
goal which can be achieved by a :ref:`strategy <strategy_definition>`.
This section gives some guidelines on how to implement and integrate custom
goals with Watcher. If you wish to create a third-party package for your
plugin, you can refer to our :ref:`documentation for third-party package
creation <plugin-base_setup>`.
Pre-requisites
==============
Before using any goal, please make sure that none of the existing goals fit
your needs. Indeed, the underlying value of defining a goal is to be able to
compare the efficacy of the action plans resulting from the various strategies
satisfying the same goal. By doing so, Watcher can assist the administrator
in his choices.
Create a new plugin
===================
In order to create a new goal, you have to:
- Extend the :py:class:`~.base.Goal` class.
- Implement its :py:meth:`~.Goal.get_name` class method to return the
**unique** ID of the new goal you want to create. This unique ID should
be the same as the name of :ref:`the entry point you will declare later on
<goal_plugin_add_entrypoint>`.
- Implement its :py:meth:`~.Goal.get_display_name` class method to
return the translated display name of the goal you want to create.
Note: Do not use a variable to return the translated string so it can be
automatically collected by the translation tool.
- Implement its :py:meth:`~.Goal.get_translatable_display_name`
class method to return the translation key (actually the english display
name) of your new goal. The value return should be the same as the
string translated in :py:meth:`~.Goal.get_display_name`.
- Implement its :py:meth:`~.Goal.get_efficacy_specification` method to return
the :ref:`efficacy specification <efficacy_specification_definition>` for
your goal.
Here is an example showing how you can define a new ``NewGoal`` goal plugin:
.. code-block:: python
# filepath: thirdparty/new.py
# import path: thirdparty.new
from watcher._i18n import _
from watcher.decision_engine.goal import base
from watcher.decision_engine.goal.efficacy import specs
class NewGoal(base.Goal):
@classmethod
def get_name(cls):
return "new_goal" # Will be the name of the entry point
@classmethod
def get_display_name(cls):
return _("New Goal")
@classmethod
def get_translatable_display_name(cls):
return "New Goal"
@classmethod
def get_efficacy_specification(cls):
return specs.Unclassified()
As you may have noticed, the :py:meth:`~.Goal.get_efficacy_specification`
method returns an :py:meth:`~.Unclassified` instance which
is provided by Watcher. This efficacy specification is useful during the
development process of your goal as it corresponds to an empty specification.
If you want to learn more about what efficacy specifications are used for or to
define your own efficacy specification, please refer to the :ref:`related
section below <implement_efficacy_specification>`.
Abstract Plugin Class
=====================
Here below is the abstract :py:class:`~.base.Goal` class:
.. autoclass:: watcher.decision_engine.goal.base.Goal
:members:
:noindex:
.. _goal_plugin_add_entrypoint:
Add a new entry point
=====================
In order for the Watcher Decision Engine to load your new goal, the
goal must be registered as a named entry point under the ``watcher_goals``
entry point namespace of your ``setup.py`` file. If you are using pbr_, this
entry point should be placed in your ``setup.cfg`` file.
The name you give to your entry point has to be unique and should be the same
as the value returned by the :py:meth:`~.base.Goal.get_name` class method of
your goal.
Here below is how you would proceed to register ``NewGoal`` using pbr_:
.. code-block:: ini
[entry_points]
watcher_goals =
new_goal = thirdparty.new:NewGoal
To get a better understanding on how to implement a more advanced goal,
have a look at the :py:class:`~.ServerConsolidation` class.
.. _pbr: http://docs.openstack.org/developer/pbr/
.. _implement_efficacy_specification:
Implement a customized efficacy specification
=============================================
What is it for?
---------------
Efficacy specifications define a set of specifications for a given goal.
These specifications actually define a list of indicators which are to be used
to compute a global efficacy that outlines how well a strategy performed when
trying to achieve the goal it is associated to.
The idea behind such specification is to give the administrator the possibility
to run an audit using different strategies satisfying the same goal and be able
to judge how they performed at a glance.
Implementation
--------------
In order to create a new efficacy specification, you have to:
- Extend the :py:class:`~.EfficacySpecification` class.
- Implement :py:meth:`~.EfficacySpecification.get_indicators_specifications`
by returning a list of :py:class:`~.IndicatorSpecification` instances.
* Each :py:class:`~.IndicatorSpecification` instance should actually extend
the latter.
* Each indicator specification should have a **unique name** which should be
a valid Python variable name.
* They should implement the :py:attr:`~.EfficacySpecification.schema`
abstract property by returning a :py:class:`~.voluptuous.Schema` instance.
This schema is the contract the strategy will have to comply with when
setting the value associated to the indicator specification within its
solution (see the :ref:`architecture of Watcher
<sequence_diagrams_create_and_launch_audit>` for more information on
the audit execution workflow).
- Implement the :py:meth:`~.EfficacySpecification.get_global_efficacy` method:
it should compute the global efficacy for the goal it achieves based on the
efficacy indicators you just defined.
Here below is an example of an efficacy specification containing one indicator
specification:
.. code-block:: python
from watcher._i18n import _
from watcher.decision_engine.goal.efficacy import base as efficacy_base
from watcher.decision_engine.goal.efficacy import indicators
from watcher.decision_engine.solution import efficacy
class IndicatorExample(IndicatorSpecification):
def __init__(self):
super(IndicatorExample, self).__init__(
name="indicator_example",
description=_("Example of indicator specification."),
unit=None,
)
@property
def schema(self):
return voluptuous.Schema(voluptuous.Range(min=0), required=True)
class UnclassifiedStrategySpecification(efficacy_base.EfficacySpecification):
def get_indicators_specifications(self):
return [IndicatorExample()]
def get_global_efficacy(self, indicators_map):
return efficacy.Indicator(
name="global_efficacy_indicator",
description="Example of global efficacy indicator",
unit="%",
value=indicators_map.indicator_example % 100)
To get a better understanding on how to implement an efficacy specification,
have a look at :py:class:`~.ServerConsolidationSpecification`.
Also, if you want to see a concrete example of an indicator specification,
have a look at :py:class:`~.ReleasedComputeNodesCount`.

View File

@@ -11,9 +11,10 @@ Build a new planner
===================
Watcher :ref:`Decision Engine <watcher_decision_engine_definition>` has an
external :ref:`planner <planner_definition>` plugin interface which gives
anyone the ability to integrate an external :ref:`planner <planner_definition>`
in order to extend the initial set of planners Watcher provides.
external :ref:`planner <watcher_planner_definition>` plugin interface which
gives anyone the ability to integrate an external :ref:`planner
<watcher_planner_definition>` in order to extend the initial set of planners
Watcher provides.
This section gives some guidelines on how to implement and integrate custom
planners with Watcher.
@@ -38,7 +39,7 @@ Here is an example showing how you can write a planner plugin called
# Filepath = third-party/third_party/dummy.py
# Import path = third_party.dummy
import uuid
from oslo_utils import uuidutils
from watcher.decision_engine.planner import base
@@ -46,7 +47,7 @@ Here is an example showing how you can write a planner plugin called
def _create_action_plan(self, context, audit_id):
action_plan_dict = {
'uuid': uuid.uuid4(),
'uuid': uuidutils.generate_uuid(),
'audit_id': audit_id,
'first_action_id': None,
'state': objects.action_plan.State.RECOMMENDED
@@ -69,6 +70,51 @@ examples, have a look at the implementation of planners already provided by
Watcher like :py:class:`~.DefaultPlanner`. A list with all available planner
plugins can be found :ref:`here <watcher_planners>`.
Define configuration parameters
===============================
At this point, you have a fully functional planner. However, in more complex
implementation, you may want to define some configuration options so one can
tune the planner to its needs. To do so, you can implement the
:py:meth:`~.Loadable.get_config_opts` class method as followed:
.. code-block:: python
from oslo_config import cfg
class DummyPlanner(base.BasePlanner):
# [...]
def schedule(self, context, audit_uuid, solution):
assert self.config.test_opt == 0
# [...]
@classmethod
def get_config_opts(cls):
return super(
DummyPlanner, cls).get_config_opts() + [
cfg.StrOpt('test_opt', help="Demo Option.", default=0),
# Some more options ...
]
The configuration options defined within this class method will be included
within the global ``watcher.conf`` configuration file under a section named by
convention: ``{namespace}.{plugin_name}``. In our case, the ``watcher.conf``
configuration would have to be modified as followed:
.. code-block:: ini
[watcher_planners.dummy]
# Option used for testing.
test_opt = test_value
Then, the configuration options you define within this method will then be
injected in each instantiated object via the ``config`` parameter of the
:py:meth:`~.BasePlanner.__init__` method.
Abstract Plugin Class
=====================
@@ -77,6 +123,7 @@ should implement:
.. autoclass:: watcher.decision_engine.planner.base.BasePlanner
:members:
:special-members: __init__
:noindex:

View File

@@ -0,0 +1,210 @@
..
Except where otherwise noted, this document is licensed under Creative
Commons Attribution 3.0 License. You can view the license at:
https://creativecommons.org/licenses/by/3.0/
.. _implement_scoring_engine_plugin:
==========================
Build a new scoring engine
==========================
Watcher Decision Engine has an external :ref:`scoring engine
<scoring_engine_definition>` plugin interface which gives anyone the ability
to integrate an external scoring engine in order to make use of it in a
:ref:`strategy <strategy_definition>`.
This section gives some guidelines on how to implement and integrate custom
scoring engines with Watcher. If you wish to create a third-party package for
your plugin, you can refer to our :ref:`documentation for third-party package
creation <plugin-base_setup>`.
Pre-requisites
==============
Because scoring engines execute a purely mathematical tasks, they typically do
not have any additional dependencies. Additional requirements might be defined
by specific scoring engine implementations. For example, some scoring engines
might require to prepare learning data, which has to be loaded during the
scoring engine startup. Some other might require some external services to be
available (e.g. if the scoring infrastructure is running in the cloud).
Create a new scoring engine plugin
==================================
In order to create a new scoring engine you have to:
- Extend the :py:class:`~.ScoringEngine` class
- Implement its :py:meth:`~.ScoringEngine.get_name` method to return the
**unique** ID of the new scoring engine you want to create. This unique ID
should be the same as the name of :ref:`the entry point we will declare later
on <scoring_engine_plugin_add_entrypoint>`.
- Implement its :py:meth:`~.ScoringEngine.get_description` method to return the
user-friendly description of the implemented scoring engine. It might contain
information about algorithm used, learning data etc.
- Implement its :py:meth:`~.ScoringEngine.get_metainfo` method to return the
machine-friendly metadata about this scoring engine. For example, it could be
a JSON formatted text with information about the data model used, its input
and output data format, column names, etc.
- Implement its :py:meth:`~.ScoringEngine.calculate_score` method to return the
result calculated by this scoring engine.
Here is an example showing how you can write a plugin called ``NewScorer``:
.. code-block:: python
# filepath: thirdparty/new.py
# import path: thirdparty.new
from watcher.decision_engine.scoring import base
class NewScorer(base.ScoringEngine):
def get_name(self):
return 'new_scorer'
def get_description(self):
return ''
def get_metainfo(self):
return """{
"feature_columns": [
"column1",
"column2",
"column3"],
"result_columns": [
"value",
"probability"]
}"""
def calculate_score(self, features):
return '[12, 0.83]'
As you can see in the above example, the
:py:meth:`~.ScoringEngine.calculate_score` method returns a string. Both this
class and the client (caller) should perform all the necessary serialization
or deserialization.
(Optional) Create a new scoring engine container plugin
=======================================================
Optionally, it's possible to implement a container plugin, which can return a
list of scoring engines. This list can be re-evaluated multiple times during
the lifecycle of :ref:`Watcher Decision Engine
<watcher_decision_engine_definition>` and synchronized with :ref:`Watcher
Database <watcher_database_definition>` using the ``watcher-sync`` command line
tool.
Below is an example of a container using some scoring engine implementation
that is simply made of a client responsible for communicating with a real
scoring engine deployed as a web service on external servers:
.. code-block:: python
class NewScoringContainer(base.ScoringEngineContainer):
@classmethod
def get_scoring_engine_list(self):
return [
RemoteScoringEngine(
name='scoring_engine1',
description='Some remote Scoring Engine 1',
remote_url='http://engine1.example.com/score'),
RemoteScoringEngine(
name='scoring_engine2',
description='Some remote Scoring Engine 2',
remote_url='http://engine2.example.com/score'),
]
Abstract Plugin Class
=====================
Here below is the abstract :py:class:`~.ScoringEngine` class:
.. autoclass:: watcher.decision_engine.scoring.base.ScoringEngine
:members:
:special-members: __init__
:noindex:
Abstract Plugin Container Class
===============================
Here below is the abstract :py:class:`~.ScoringContainer` class:
.. autoclass:: watcher.decision_engine.scoring.base.ScoringEngineContainer
:members:
:special-members: __init__
:noindex:
.. _scoring_engine_plugin_add_entrypoint:
Add a new entry point
=====================
In order for the Watcher Decision Engine to load your new scoring engine, it
must be registered as a named entry point under the ``watcher_scoring_engines``
entry point of your ``setup.py`` file. If you are using pbr_, this entry point
should be placed in your ``setup.cfg`` file.
The name you give to your entry point has to be unique and should be the same
as the value returned by the :py:meth:`~.ScoringEngine.get_name` method of your
strategy.
Here below is how you would proceed to register ``NewScorer`` using pbr_:
.. code-block:: ini
[entry_points]
watcher_scoring_engines =
new_scorer = thirdparty.new:NewScorer
To get a better understanding on how to implement a more advanced scoring
engine, have a look at the :py:class:`~.DummyScorer` class. This implementation
is not really using machine learning, but other than that it contains all the
pieces which the "real" implementation would have.
In addition, for some use cases there is a need to register a list (possibly
dynamic, depending on the implementation and configuration) of scoring engines
in a single plugin, so there is no need to restart :ref:`Watcher Decision
Engine <watcher_decision_engine_definition>` every time such list changes. For
these cases, an additional ``watcher_scoring_engine_containers`` entry point
can be used.
For the example how to use scoring engine containers, please have a look at
the :py:class:`~.DummyScoringContainer` and the way it is configured in
``setup.cfg``. For new containers it could be done like this:
.. code-block:: ini
[entry_points]
watcher_scoring_engine_containers =
new_scoring_container = thirdparty.new:NewContainer
.. _pbr: http://docs.openstack.org/developer/pbr/
Using scoring engine plugins
============================
The Watcher Decision Engine service will automatically discover any installed
plugins when it is restarted. If a Python package containing a custom plugin is
installed within the same environment as Watcher, Watcher will automatically
make that plugin available for use.
At this point, Watcher will scan and register inside the :ref:`Watcher Database
<watcher_database_definition>` all the scoring engines you implemented upon
restarting the :ref:`Watcher Decision Engine
<watcher_decision_engine_definition>`.
In addition, ``watcher-sync`` tool can be used to trigger :ref:`Watcher
Database <watcher_database_definition>` synchronization. This might be used for
"dynamic" scoring containers, which can return different scoring engines based
on some external configuration (if they support that).

View File

@@ -15,7 +15,9 @@ plugin interface which gives anyone the ability to integrate an external
strategy in order to make use of placement algorithms.
This section gives some guidelines on how to implement and integrate custom
strategies with Watcher.
strategies with Watcher. If you wish to create a third-party package for your
plugin, you can refer to our :ref:`documentation for third-party package
creation <plugin-base_setup>`.
Pre-requisites
@@ -26,64 +28,172 @@ configured so that it would provide you all the metrics you need to be able to
use your strategy.
Creating a new plugin
=====================
Create a new strategy plugin
============================
First of all you have to:
In order to create a new strategy, you have to:
- Extend :py:class:`~.BaseStrategy`
- Implement its :py:meth:`~.BaseStrategy.execute` method
- Extend the :py:class:`~.UnclassifiedStrategy` class
- Implement its :py:meth:`~.BaseStrategy.get_name` class method to return the
**unique** ID of the new strategy you want to create. This unique ID should
be the same as the name of :ref:`the entry point we will declare later on
<strategy_plugin_add_entrypoint>`.
- Implement its :py:meth:`~.BaseStrategy.get_display_name` class method to
return the translated display name of the strategy you want to create.
Note: Do not use a variable to return the translated string so it can be
automatically collected by the translation tool.
- Implement its :py:meth:`~.BaseStrategy.get_translatable_display_name`
class method to return the translation key (actually the English display
name) of your new strategy. The value return should be the same as the
string translated in :py:meth:`~.BaseStrategy.get_display_name`.
- Implement its :py:meth:`~.BaseStrategy.execute` method to return the
solution you computed within your strategy.
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 ``NewStrategy``:
.. code-block:: python
import uuid
# filepath: thirdparty/new.py
# import path: thirdparty.new
import abc
class DummyStrategy(BaseStrategy):
import six
DEFAULT_NAME = "dummy"
DEFAULT_DESCRIPTION = "Dummy Strategy"
from watcher._i18n import _
from watcher.decision_engine.strategy.strategies import base
def __init__(self, name=DEFAULT_NAME, description=DEFAULT_DESCRIPTION):
super(DummyStrategy, self).__init__(name, description)
def execute(self, model):
migration_type = 'live'
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,
class NewStrategy(base.UnclassifiedStrategy):
def __init__(self, osc=None):
super(NewStrategy, self).__init__(osc)
def execute(self, original_model):
self.solution.add_action(action_type="nop",
input_parameters=parameters)
# Do some more stuff here ...
return self.solution
@classmethod
def get_name(cls):
return "new_strategy"
@classmethod
def get_display_name(cls):
return _("New strategy")
@classmethod
def get_translatable_display_name(cls):
return "New strategy"
As you can see in the above example, the :py:meth:`~.BaseStrategy.execute`
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>`.
solution is then processed by a :ref:`planner <watcher_planner_definition>` to
produce an action plan which contains the sequenced flow of actions to be
executed by the :ref:`Watcher Applier <watcher_applier_definition>`. This
solution also contains the various :ref:`efficacy indicators
<efficacy_indicator_definition>` alongside its computed :ref:`global efficacy
<efficacy_definition>`.
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
your ``__init__`` method.
Please note that your strategy class will expect to find the same constructor
signature as BaseStrategy to instantiate you strategy. Therefore, you should
ensure that your ``__init__`` signature is identical to the
:py:class:`~.BaseStrategy` one.
Strategy efficacy
=================
As stated before, the ``NewStrategy`` class extends a class called
:py:class:`~.UnclassifiedStrategy`. This class actually implements a set of
abstract methods which are defined within the :py:class:`~.BaseStrategy` parent
class.
One thing this :py:class:`~.UnclassifiedStrategy` class defines is that our
``NewStrategy`` achieves the ``unclassified`` goal. This goal is a peculiar one
as it does not contain any indicator nor does it calculate a global efficacy.
This proves itself to be quite useful during the development of a new strategy
for which the goal has yet to be defined or in case a :ref:`new goal
<implement_goal_plugin>` has yet to be implemented.
Define Strategy Parameters
==========================
For each new added strategy, you can add parameters spec so that an operator
can input strategy parameters when creating an audit to control the
:py:meth:`~.BaseStrategy.execute` behavior of strategy. This is useful to
define some threshold for your strategy, and tune them at runtime.
To define parameters, just implements :py:meth:`~.BaseStrategy.get_schema` to
return parameters spec with `jsonschema
<http://json-schema.org/>`_ format.
It is strongly encouraged that provide default value for each parameter, or
else reference fails if operator specify no parameters.
Here is an example showing how you can define 2 parameters for
``DummyStrategy``:
.. code-block:: python
class DummyStrategy(base.DummyBaseStrategy):
@classmethod
def get_schema(cls):
return {
"properties": {
"para1": {
"description": "number parameter example",
"type": "number",
"default": 3.2,
"minimum": 1.0,
"maximum": 10.2,
},
"para2": {
"description": "string parameter example",
"type": "string",
"default": "hello",
},
},
}
You can reference parameters in :py:meth:`~.BaseStrategy.execute`:
.. code-block:: python
class DummyStrategy(base.DummyBaseStrategy):
def execute(self):
para1 = self.input_parameters.para1
para2 = self.input_parameters.para2
if para1 > 5:
...
Operator can specify parameters with following commands:
.. code:: bash
$ watcher audit create -a <your_audit_template> -p para1=6.0 -p para2=hi
Pls. check user-guide for details.
Abstract Plugin Class
=====================
Here below is the abstract :py:class:`~.BaseStrategy` class that every single
strategy should implement:
Here below is the abstract :py:class:`~.BaseStrategy` class:
.. autoclass:: watcher.decision_engine.strategy.strategies.base.BaseStrategy
:members:
:special-members: __init__
:noindex:
.. _strategy_plugin_add_entrypoint:
Add a new entry point
=====================
@@ -93,15 +203,17 @@ strategy must be registered as a named entry point under the
``watcher_strategies`` entry point of your ``setup.py`` file. If you are using
pbr_, this entry point should be placed in your ``setup.cfg`` file.
The name you give to your entry point has to be unique.
The name you give to your entry point has to be unique and should be the same
as the value returned by the :py:meth:`~.BaseStrategy.get_name` class method of
your strategy.
Here below is how you would proceed to register ``DummyStrategy`` using pbr_:
Here below is how you would proceed to register ``NewStrategy`` using pbr_:
.. code-block:: ini
[entry_points]
watcher_strategies =
dummy = thirdparty.dummy:DummyStrategy
new_strategy = thirdparty.new:NewStrategy
To get a better understanding on how to implement a more advanced strategy,
@@ -117,16 +229,10 @@ plugins when it is restarted. If a Python package containing a custom plugin is
installed within the same environment as Watcher, Watcher will automatically
make that plugin available for use.
At this point, Watcher will use your new strategy if you reference it in the
``goals`` under the ``[watcher_goals]`` section of your ``watcher.conf``
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:
.. code-block:: ini
[watcher_goals]
goals = BALANCE_LOAD:basic,MINIMIZE_ENERGY_CONSUMPTION:dummy
At this point, Watcher will scan and register inside the :ref:`Watcher Database
<watcher_database_definition>` all the strategies (alongside the goals they
should satisfy) you implemented upon restarting the :ref:`Watcher Decision
Engine <watcher_decision_engine_definition>`.
You should take care when installing strategy plugins. By their very nature,
there are no guarantees that utilizing them as is will be supported, as
@@ -139,23 +245,30 @@ Querying metrics
A large set of metrics, generated by OpenStack modules, can be used in your
strategy implementation. To collect these metrics, Watcher provides a
`Helper`_ to the Ceilometer API, which makes this API reusable and easier
to used.
`Helper`_ for two data sources which are `Ceilometer`_ and `Monasca`_. If you
wish to query metrics from a different data source, you can implement your own
and directly use it from within your new strategy. Indeed, strategies in
Watcher have the cluster data models decoupled from the data sources which
means that you may keep the former while changing the latter.
The recommended way for you to support a new data source is to implement a new
helper that would encapsulate within separate methods the queries you need to
perform. To then use it, you would just have to instantiate it within your
strategy.
If you want to use your own metrics database backend, please refer to the
`Ceilometer developer guide`_. Indeed, Ceilometer's pluggable model allows
for various types of backends. A list of the available backends is located
here_. The Ceilosca project is a good example of how to create your own
pluggable backend.
If you want to use Ceilometer but with your own metrics database backend,
please refer to the `Ceilometer developer guide`_. The list of the available
Ceilometer backends is located here_. The `Ceilosca`_ project is a good example
of how to create your own pluggable backend. Moreover, if your strategy
requires new metrics not covered by Ceilometer, you can add them through a
`Ceilometer plugin`_.
Finally, if your strategy requires new metrics not covered by Ceilometer, you
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/decision_engine/cluster/history/ceilometer.py
.. _`Ceilometer developer guide`: http://docs.openstack.org/developer/ceilometer/architecture.html#storing-the-data
.. _`Ceilometer`: http://docs.openstack.org/developer/ceilometer/
.. _`Monasca`: https://github.com/openstack/monasca-api/blob/master/docs/monasca-api-spec.md
.. _`here`: http://docs.openstack.org/developer/ceilometer/install/dbreco.html#choosing-a-database-backend
.. _`plugin`: http://docs.openstack.org/developer/ceilometer/plugins.html
.. _`Ceilometer plugin`: http://docs.openstack.org/developer/ceilometer/plugins.html
.. _`Ceilosca`: https://github.com/openstack/monasca-ceilometer/blob/master/ceilosca/ceilometer/storage/impl_monasca.py
@@ -191,16 +304,15 @@ Read usage metrics using the Watcher Cluster History Helper
Here below is the abstract ``BaseClusterHistory`` class of the Helper.
.. autoclass:: watcher.metrics_engine.cluster_history.api.BaseClusterHistory
.. autoclass:: watcher.decision_engine.cluster.history.base.BaseClusterHistory
:members:
:noindex:
The following code snippet shows how to create a Cluster History class:
.. code-block:: py
from watcher.metrics_engine.cluster_history import ceilometer as ceil
from watcher.decision_engine.cluster.history import ceilometer as ceil
query_history = ceil.CeilometerClusterHistory()
@@ -208,7 +320,7 @@ Using that you can now query the values for that specific metric:
.. code-block:: py
query_history.statistic_aggregation(resource_id=hypervisor.uuid,
query_history.statistic_aggregation(resource_id=compute_node.uuid,
meter_name='compute.node.cpu.percent',
period="7200",
aggregate='avg'

View File

@@ -9,30 +9,68 @@
Available Plugins
=================
In this section we present all the plugins that are shipped along with Watcher.
If you want to know which plugins your Watcher services have access to, you can
use the :ref:`Guru Meditation Reports <watcher_gmr>` to display them.
.. _watcher_goals:
Goals
=====
.. list-plugins:: watcher_goals
:detailed:
.. _watcher_scoring_engines:
Scoring Engines
===============
.. list-plugins:: watcher_scoring_engines
:detailed:
.. _watcher_scoring_engine_containers:
Scoring Engine Containers
=========================
.. list-plugins:: watcher_scoring_engine_containers
:detailed:
.. _watcher_strategies:
Strategies
==========
.. drivers-doc:: watcher_strategies
.. list-plugins:: watcher_strategies
:detailed:
.. _watcher_actions:
Actions
=======
.. drivers-doc:: watcher_actions
.. list-plugins:: watcher_actions
:detailed:
.. _watcher_workflow_engines:
Workflow Engines
================
.. drivers-doc:: watcher_workflow_engines
.. list-plugins:: watcher_workflow_engines
:detailed:
.. _watcher_planners:
Planners
========
.. drivers-doc:: watcher_planners
.. list-plugins:: watcher_planners
:detailed:
Cluster Data Model Collectors
=============================
.. list-plugins:: watcher_cluster_data_model_collectors
:detailed:

View File

@@ -0,0 +1 @@
.. include:: ../../../rally-jobs/README.rst

View File

@@ -96,17 +96,17 @@ The :ref:`Cluster <cluster_definition>` may be divided in one or several
.. _cluster_data_model_definition:
Cluster Data Model
==================
Cluster Data Model (CDM)
========================
.. watcher-term:: watcher.metrics_engine.cluster_model_collector.api
.. watcher-term:: watcher.decision_engine.model.collector.base
.. _cluster_history_definition:
Cluster History
===============
.. watcher-term:: watcher.metrics_engine.cluster_history.api
.. watcher-term:: watcher.decision_engine.cluster.history.base
.. _controller_node_definition:
@@ -131,7 +131,8 @@ can potentially be hosted on a dedicated machine.
Compute node
============
Please, read `the official OpenStack definition of a Compute Node <http://docs.openstack.org/openstack-ops/content/compute_nodes.html>`_.
Please, read `the official OpenStack definition of a Compute Node
<http://docs.openstack.org/ops-guide/arch-compute-nodes.html>`_.
.. _customer_definition:
@@ -163,7 +164,8 @@ Goal
Host Aggregate
==============
Please, read `the official OpenStack definition of a Host Aggregate <http://docs.openstack.org/developer/nova/aggregates.html>`_.
Please, read `the official OpenStack definition of a Host Aggregate
<http://docs.openstack.org/developer/nova/aggregates.html>`_.
.. _instance_definition:
@@ -211,7 +213,23 @@ Here are some examples of
- `Sahara Hadoop Cluster <http://docs.openstack.org/developer/heat/template_guide/openstack.html#OS::Sahara::Cluster>`_
- ...
It can be any of the `the official list of available resource types defined in OpenStack for HEAT <http://docs.openstack.org/developer/heat/template_guide/openstack.html>`_.
It can be any of the `the official list of available resource types defined in
OpenStack for HEAT
<http://docs.openstack.org/developer/heat/template_guide/openstack.html>`_.
.. _efficacy_indicator_definition:
Efficacy Indicator
==================
.. watcher-term:: watcher.api.controllers.v1.efficacy_indicator
.. _efficacy_specification_definition:
Efficacy Specification
======================
.. watcher-term:: watcher.decision_engine.goal.efficacy.base
.. _efficacy_definition:
@@ -223,8 +241,8 @@ measure of how much of the :ref:`Goal <goal_definition>` has been achieved in
respect with constraints and :ref:`SLAs <sla_definition>` defined by the
:ref:`Customer <customer_definition>`.
The way efficacy is evaluated will depend on the
:ref:`Goal <goal_definition>` to achieve.
The way efficacy is evaluated will depend on the :ref:`Goal <goal_definition>`
to achieve.
Of course, the efficacy will be relevant only as long as the
:ref:`Action Plan <action_plan_definition>` is relevant
@@ -234,14 +252,15 @@ to be launched).
For example, if the :ref:`Goal <goal_definition>` is to lower the energy
consumption, the :ref:`Efficacy <efficacy_definition>` will be computed
using several indicators (KPIs):
using several :ref:`efficacy indicators <efficacy_indicator_definition>`
(KPIs):
- the percentage of energy gain (which must be the highest possible)
- the number of :ref:`SLA violations <sla_violation_definition>`
(which must be the lowest possible)
- the number of virtual machine migrations (which must be the lowest possible)
All those indicators (KPIs) are computed within a given timeframe, which is the
All those indicators are computed within a given timeframe, which is the
time taken to execute the whole :ref:`Action Plan <action_plan_definition>`.
The efficacy also enables the :ref:`Administrator <administrator_definition>`
@@ -259,8 +278,15 @@ OpenStack should be owned by a specific :ref:`project <project_definition>`.
In OpenStack Identity, a :ref:`project <project_definition>` must be owned by a
specific domain.
Please, read `the official OpenStack definition of a Project <http://docs.openstack.org/glossary/content/glossary.html>`_.
Please, read `the official OpenStack definition of a Project
<http://docs.openstack.org/glossary/content/glossary.html>`_.
.. _scoring_engine_definition:
Scoring Engine
==============
.. watcher-term:: watcher.api.controllers.v1.scoring_engine
.. _sla_definition:
@@ -323,7 +349,7 @@ Solution
Strategy
========
.. watcher-term:: watcher.decision_engine.strategy.strategies.base
.. watcher-term:: watcher.api.controllers.v1.strategy
.. _watcher_applier_definition:
@@ -364,4 +390,3 @@ Watcher Planner
===============
.. watcher-term:: watcher.decision_engine.planner.base

View File

@@ -0,0 +1,14 @@
plantuml
========
To build an image from a source file, you have to upload the plantuml JAR file
available on http://plantuml.com/download.html.
After, just run this command to build your image:
.. code-block:: shell
$ cd doc/source/images
$ java -jar /path/to/plantuml.jar doc/source/image_src/plantuml/my_image.txt
$ ls doc/source/images/
my_image.png

View File

@@ -0,0 +1,41 @@
@startuml
skinparam maxMessageSize 100
actor "Administrator"
== Initialization ==
"Administrator" -> "Decision Engine" : Start all services
"Decision Engine" -> "Background Task Scheduler" : Start
activate "Background Task Scheduler"
"Background Task Scheduler" -> "Cluster Model Collector Loader"\
: List available cluster data models
"Cluster Model Collector Loader" --> "Background Task Scheduler"\
: list of BaseClusterModelCollector instances
loop for every available cluster data model collector
"Background Task Scheduler" -> "Background Task Scheduler"\
: add periodic synchronization job
create "Jobs Pool"
"Background Task Scheduler" -> "Jobs Pool" : Create sync job
end
deactivate "Background Task Scheduler"
hnote over "Background Task Scheduler" : Idle
== Job workflow ==
"Background Task Scheduler" -> "Jobs Pool" : Trigger synchronization job
"Jobs Pool" -> "Nova Cluster Data Model Collector" : synchronize
activate "Nova Cluster Data Model Collector"
"Nova Cluster Data Model Collector" -> "Nova API"\
: Fetch needed data to build the cluster data model
"Nova API" --> "Nova Cluster Data Model Collector" : Needed data
"Nova Cluster Data Model Collector" -> "Nova Cluster Data Model Collector"\
: Build an in-memory cluster data model
]o<-- "Nova Cluster Data Model Collector" : Done
deactivate "Nova Cluster Data Model Collector"
@enduml

View File

@@ -3,7 +3,7 @@
actor Administrator
Administrator -> "Watcher CLI" : watcher audit-create -a <audit_template_uuid>
Administrator -> "Watcher CLI" : watcher audit create -a <audit_template>
"Watcher CLI" -> "Watcher API" : POST audit(parameters)
"Watcher API" -> "Watcher Database" : create new audit in database (status=PENDING)
@@ -14,7 +14,7 @@ Administrator -> "Watcher CLI" : watcher audit-create -a <audit_template_uuid>
Administrator <-- "Watcher CLI" : new audit uuid
"Watcher API" -> "AMQP Bus" : trigger_audit(new_audit.uuid)
"AMQP Bus" -> "Watcher Decision Engine" : trigger_audit(new_audit.uuid)
"AMQP Bus" -> "Watcher Decision Engine" : trigger_audit(new_audit.uuid) (status=ONGOING)
ref over "Watcher Decision Engine"
Trigger audit in the

View File

@@ -2,15 +2,21 @@
actor Administrator
Administrator -> "Watcher CLI" : watcher audit-template-create <name> <goal>
Administrator -> "Watcher CLI" : watcher audittemplate create <name> <goal> \
[--strategy-uuid <strategy>]
"Watcher CLI" -> "Watcher API" : POST audit_template(parameters)
"Watcher API" -> "Watcher API" : make sure goal exist in configuration
"Watcher API" -> "Watcher Database" : create new audit_template in database
"Watcher API" -> "Watcher Database" : Request if goal exists in database
"Watcher API" <-- "Watcher Database" : OK
"Watcher API" <-- "Watcher Database" : new audit template uuid
"Watcher CLI" <-- "Watcher API" : return new audit template URL in HTTP Location Header
Administrator <-- "Watcher CLI" : new audit template uuid
"Watcher API" -> "Watcher Database" : Request if strategy exists in database (if provided)
"Watcher API" <-- "Watcher Database" : OK
"Watcher API" -> "Watcher Database" : Create new audit_template in database
"Watcher API" <-- "Watcher Database" : New audit template UUID
"Watcher CLI" <-- "Watcher API" : Return new audit template URL in HTTP Location Header
Administrator <-- "Watcher CLI" : New audit template UUID
@enduml

View File

@@ -0,0 +1,44 @@
@startuml
skinparam maxMessageSize 200
"Decision Engine" -> "Decision Engine" : Execute audit
activate "Decision Engine"
"Decision Engine" -> "Decision Engine" : Set the audit state to ONGOING
"Decision Engine" -> "Strategy selector" : Select strategy
activate "Strategy selector"
alt A specific strategy is provided
"Strategy selector" -> "Strategy selector" : Load strategy and inject the \
cluster data model
else Only a goal is specified
"Strategy selector" -> "Strategy selector" : select strategy
"Strategy selector" -> "Strategy selector" : Load strategy and inject the \
cluster data model
end
"Strategy selector" -> "Decision Engine" : Return loaded Strategy
deactivate "Strategy selector"
"Decision Engine" -> "Strategy" : Execute the strategy
activate "Strategy"
"Strategy" -> "Strategy" : **pre_execute()**Checks if the strategy \
pre-requisites are all set.
"Strategy" -> "Strategy" : **do_execute()**Contains the logic of the strategy
"Strategy" -> "Strategy" : **post_execute()** Set the efficacy indicators
"Strategy" -> "Strategy" : Compute the global efficacy of the solution \
based on the provided efficacy indicators
"Strategy" -> "Decision Engine" : Return the solution
deactivate "Strategy"
"Decision Engine" -> "Planner" : Plan the solution that was computed by the \
strategy
activate "Planner"
"Planner" -> "Planner" : Store the planned solution as an action plan with its \
related actions and efficacy indicators
"Planner" --> "Decision Engine" : Done
deactivate "Planner"
"Decision Engine" -> "Decision Engine" : Update the audit state to SUCCEEDED
deactivate "Decision Engine"
@enduml

View File

@@ -2,10 +2,10 @@
actor Administrator
Administrator -> "Watcher CLI" : watcher action-plan-start <action_plan_uuid>
Administrator -> "Watcher CLI" : watcher actionplan start <action_plan_uuid>
"Watcher CLI" -> "Watcher API" : PATCH action_plan(state=TRIGGERED)
"Watcher API" -> "Watcher Database" : action_plan.state=TRIGGERED
"Watcher CLI" -> "Watcher API" : PATCH action_plan(state=PENDING)
"Watcher API" -> "Watcher Database" : action_plan.state=PENDING
"Watcher CLI" <-- "Watcher API" : HTTP 200

View File

@@ -4,7 +4,7 @@ actor Administrator
== Create some Audit settings ==
Administrator -> Watcher : create new Audit Template (i.e. Audit settings : goal, scope, deadline,...)
Administrator -> Watcher : create new Audit Template (i.e. Audit settings : goal, scope, ...)
Watcher -> Watcher : save Audit Template in database
Administrator <-- Watcher : Audit Template UUID

View File

@@ -1,31 +1,50 @@
@startuml
"AMQP Bus" -> "Watcher Decision Engine" : trigger_audit(new_audit.uuid)
"Watcher Decision Engine" -> "Watcher Database" : update audit.state = ONGOING
"AMQP Bus" <[#blue]- "Watcher Decision Engine" : notify new audit state = ONGOING
"Watcher Decision Engine" -> "Watcher Database" : get audit parameters(goal, ...)
"Watcher Decision Engine" <-- "Watcher Database" : audit parameters(goal, ...)
skinparam maxMessageSize 100
"AMQP Bus" -> "Decision Engine" : trigger audit
activate "Decision Engine"
"Decision Engine" -> "Database" : update audit.state = ONGOING
"AMQP Bus" <[#blue]- "Decision Engine" : notify new audit state = ONGOING
"Decision Engine" -> "Database" : get audit parameters (goal, strategy, ...)
"Decision Engine" <-- "Database" : audit parameters (goal, strategy, ...)
"Decision Engine" --> "Decision Engine"\
: select appropriate optimization strategy (via the Strategy Selector)
create Strategy
"Watcher Decision Engine" -[#red]> "Strategy": select appropriate\noptimization strategy
loop while enough data to build cluster data model
"Watcher Decision Engine" -> "Nova API" : get resource state (host, instance, ...)
"Watcher Decision Engine" <-- "Nova API" : resource state
end
"Watcher Decision Engine" -[#red]> "Watcher Decision Engine": build cluster_data_model
"Watcher Decision Engine" -> "Strategy" : execute(cluster_data_model)
loop while enough history data for the strategy
"Strategy" -> "Ceilometer API": get_aggregated_metrics\n(resource_id,meter_name,period,aggregate_method)
"Strategy" <-- "Ceilometer API": aggregated metrics
end
"Strategy" -> "Strategy" : compute solution to achieve goal
"Watcher Decision Engine" <-- "Strategy" : solution = array of actions (i.e. not scheduled yet)
create "Watcher Planner"
"Watcher Decision Engine" -[#red]> "Watcher Planner": select appropriate actions scheduler (i.e. Planner implementation)
"Watcher Decision Engine" -> "Watcher Planner": schedule(audit_id, solution)
"Watcher Planner" -> "Watcher Planner": schedule actions according to\nscheduling rules/policies
"Watcher Decision Engine" <-- "Watcher Planner": new action_plan
"Watcher Decision Engine" -> "Watcher Database" : save new action_plan in database
"Watcher Decision Engine" -> "Watcher Database" : update audit.state = SUCCEEDED
"AMQP Bus" <[#blue]- "Watcher Decision Engine" : notify new audit state = SUCCEEDED
"Decision Engine" -> "Strategy" : execute strategy
activate "Strategy"
"Strategy" -> "Cluster Data Model Collector" : get cluster data model
"Cluster Data Model Collector" --> "Strategy"\
: copy of the in-memory cluster data model
loop while enough history data for the strategy
"Strategy" -> "Ceilometer API" : get necessary metrics
"Strategy" <-- "Ceilometer API" : aggregated metrics
end
"Strategy" -> "Strategy"\
: compute/set needed actions for the solution so it achieves its goal
"Strategy" -> "Strategy" : compute/set efficacy indicators for the solution
"Strategy" -> "Strategy" : compute/set the solution global efficacy
"Decision Engine" <-- "Strategy"\
: solution (unordered actions, efficacy indicators and global efficacy)
deactivate "Strategy"
create "Planner"
"Decision Engine" -> "Planner" : load actions scheduler
"Planner" --> "Decision Engine" : planner plugin
"Decision Engine" -> "Planner" : schedule actions
activate "Planner"
"Planner" -> "Planner"\
: schedule actions according to scheduling rules/policies
"Decision Engine" <-- "Planner" : new action plan
deactivate "Planner"
"Decision Engine" -> "Database" : save new action plan in database
"Decision Engine" -> "Database" : update audit.state = SUCCEEDED
"AMQP Bus" <[#blue]- "Decision Engine" : notify new audit state = SUCCEEDED
deactivate "Decision Engine"
hnote over "Decision Engine" : Idle
@enduml

View File

@@ -0,0 +1,153 @@
@startuml
!define table(x) class x << (T,#FFAAAA) >>
!define primary_key(x) <u>x</u>
!define foreign_key(x) <i><u>x</u></i>
hide methods
hide stereotypes
table(goals) {
primary_key(id: Integer)
uuid : String[36]
name : String[63]
display_name : String[63]
efficacy_specification : JSONEncodedList, nullable
created_at : DateTime
updated_at : DateTime
deleted_at : DateTime
deleted : Integer
}
table(strategies) {
primary_key(id: Integer)
foreign_key(goal_id : Integer)
uuid : String[36]
name : String[63]
display_name : String[63]
parameters_spec : JSONEncodedDict, nullable
created_at : DateTime
updated_at : DateTime
deleted_at : DateTime
deleted : Integer
}
table(audit_templates) {
primary_key(id: Integer)
foreign_key("goal_id : Integer")
foreign_key("strategy_id : Integer, nullable")
uuid : String[36]
name : String[63], nullable
description : String[255], nullable
scope : JSONEncodedList
created_at : DateTime
updated_at : DateTime
deleted_at : DateTime
deleted : Integer
}
table(audits) {
primary_key(id: Integer)
foreign_key("goal_id : Integer")
foreign_key("strategy_id : Integer, nullable")
uuid : String[36]
audit_type : String[20]
state : String[20], nullable
interval : Integer, nullable
parameters : JSONEncodedDict, nullable
scope : JSONEncodedList, nullable
created_at : DateTime
updated_at : DateTime
deleted_at : DateTime
deleted : Integer
}
table(action_plans) {
primary_key(id: Integer)
foreign_key("audit_id : Integer, nullable")
foreign_key("strategy_id : Integer")
uuid : String[36]
first_action_id : Integer
state : String[20], nullable
global_efficacy : JSONEncodedDict, nullable
created_at : DateTime
updated_at : DateTime
deleted_at : DateTime
deleted : Integer
}
table(actions) {
primary_key(id: Integer)
foreign_key("action_plan_id : Integer")
uuid : String[36]
action_type : String[255]
input_parameters : JSONEncodedDict, nullable
state : String[20], nullable
next : String[36], nullable
created_at : DateTime
updated_at : DateTime
deleted_at : DateTime
deleted : Integer
}
table(efficacy_indicators) {
primary_key(id: Integer)
foreign_key("action_plan_id : Integer")
uuid : String[36]
name : String[63]
description : String[255], nullable
unit : String[63], nullable
value : Numeric
created_at : DateTime
updated_at : DateTime
deleted_at : DateTime
deleted : Integer
}
table(scoring_engines) {
primary_key(id: Integer)
uuid : String[36]
name : String[63]
description : String[255], nullable
metainfo : Text, nullable
created_at : DateTime
updated_at : DateTime
deleted_at : DateTime
deleted : Integer
}
table(service) {
primary_key(id: Integer)
name: String[255]
host: String[255]
last_seen_up: DateTime
created_at : DateTime
updated_at : DateTime
deleted_at : DateTime
deleted : Integer
}
"goals" <.. "strategies" : Foreign Key
"goals" <.. "audit_templates" : Foreign Key
"strategies" <.. "audit_templates" : Foreign Key
"goals" <.. "audits" : Foreign Key
"strategies" <.. "audits" : Foreign Key
"action_plans" <.. "actions" : Foreign Key
"action_plans" <.. "efficacy_indicators" : Foreign Key
"strategies" <.. "action_plans" : Foreign Key
"audits" <.. "action_plans" : Foreign Key
@enduml

View File

@@ -1,139 +1,600 @@
<?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="58cm" height="28cm" viewBox="26 8 1147 549" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g>
<rect style="fill: #ffffff" x="570" y="99" width="148.6" height="28"/>
<rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="570" y="99" width="148.6" height="28"/>
<text font-size="16" style="fill: #000000;text-anchor:middle;font-family:sans-serif;font-style:normal;font-weight:700" x="644.3" y="118">Audit Template</text>
</g>
<g>
<rect style="fill: #ffffff" x="212" y="140" width="177.5" height="28"/>
<rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="212" y="140" width="177.5" height="28"/>
<text font-size="16" style="fill: #000000;text-anchor:middle;font-family:sans-serif;font-style:normal;font-weight:700" x="300.75" y="159">OpenStack Cluster</text>
</g>
<g>
<polyline style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 8; stroke: #000000" points="569.006,113 446,113 446,154 397.19,154 "/>
<polyline style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" points="409.838,149 393.838,154 409.838,159 "/>
<text font-size="12.7998" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="448" y="130.5">Applies to</text>
</g>
<g>
<rect style="fill: #ffffff" x="615" y="227" width="58.4" height="28"/>
<rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="615" y="227" width="58.4" height="28"/>
<text font-size="16" style="fill: #000000;text-anchor:middle;font-family:sans-serif;font-style:normal;font-weight:700" x="644.2" y="246">Audit</text>
</g>
<g>
<polyline style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 8; stroke: #000000" points="644.2,225.996 644.2,188.497 644.3,188.497 644.3,133.705 "/>
<polyline style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" points="649.3,146.353 644.3,130.353 639.3,146.353 "/>
<text font-size="12.7998" style="fill: #000000;text-anchor:middle;font-family:monospace;font-style:normal;font-weight:normal" x="644.25" y="185.497">gets configuration from</text>
</g>
<g>
<rect style="fill: #ffffff" x="916" y="9" width="50.45" height="28"/>
<rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="916" y="9" width="50.45" height="28"/>
<text font-size="16" style="fill: #000000;text-anchor:middle;font-family:sans-serif;font-style:normal;font-weight:700" x="941.225" y="28">Goal</text>
</g>
<g>
<polyline style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 8; stroke: #000000" points="644.3,97.9927 644.3,72 941.225,72 941.225,44.7125 "/>
<polyline style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" points="946.225,57.3599 941.225,41.3599 936.225,57.3599 "/>
<text font-size="12.7998" style="fill: #000000;text-anchor:middle;font-family:monospace;font-style:normal;font-weight:normal" x="792.763" y="69">Achieves</text>
</g>
<g>
<rect style="fill: #ffffff" x="495" y="367" width="112.45" height="28"/>
<rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="495" y="367" width="112.45" height="28"/>
<text font-size="16" style="fill: #000000;text-anchor:middle;font-family:sans-serif;font-style:normal;font-weight:700" x="551.225" y="386">Action Plan</text>
</g>
<g>
<polyline style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 8; stroke: #000000" points="644.2,256 644.2,298.5 523,298.5 523,356.295 "/>
<polyline style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" points="518,343.647 523,359.647 528,343.647 "/>
<text font-size="12.7998" style="fill: #000000;text-anchor:middle;font-family:monospace;font-style:normal;font-weight:normal" x="583.6" y="295.5">Generates</text>
</g>
<g>
<rect style="fill: #ffffff" x="682" y="471" width="67.45" height="28"/>
<rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="682" y="471" width="67.45" height="28"/>
<text font-size="16" style="fill: #000000;text-anchor:middle;font-family:sans-serif;font-style:normal;font-weight:700" x="715.725" y="490">Action</text>
</g>
<g>
<polyline style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" points="551.225,420.945 551.225,443 715.725,443 715.725,470.029 "/>
<polygon style="fill: #000000" points="551.225,395.773 556.025,409.773 551.225,423.773 546.425,409.773 "/>
<polygon style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" points="551.225,395.773 556.025,409.773 551.225,423.773 546.425,409.773 "/>
<text font-size="12.7998" style="fill: #000000;text-anchor:middle;font-family:monospace;font-style:normal;font-weight:normal" x="633.475" y="440">is composed of</text>
<text font-size="12.7998" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="562.225" y="407.773"></text>
<text font-size="12.7998" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="719.725" y="466.029"></text>
</g>
<g>
<polyline style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" points="749.45,499 749.45,517 862,517 862,485 749.45,485 "/>
<text font-size="12.7998" style="fill: #000000;text-anchor:middle;font-family:monospace;font-style:normal;font-weight:normal" x="805.725" y="514">Next action</text>
<polygon style="fill: #000000" points="850.075,514 850.075,506 858.075,510 "/>
<text font-size="12.7998" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="753.45" y="511"></text>
<text font-size="12.7998" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="753.45" y="482"></text>
</g>
<g>
<ellipse style="fill: #ffffff" cx="1036" cy="219" rx="6" ry="6"/>
<ellipse style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #ff0000" cx="1036" cy="219" rx="6" ry="6"/>
<line style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #ff0000" x1="1012" y1="231" x2="1060" y2="231"/>
<line style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #ff0000" x1="1036" y1="225" x2="1036" y2="255"/>
<line style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #ff0000" x1="1036" y1="255" x2="1012" y2="281"/>
<line style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #ff0000" x1="1036" y1="255" x2="1060" y2="281"/>
<text font-size="12.8" style="fill: #ff0000;text-anchor:middle;font-family:sans-serif;font-style:normal;font-weight:700" x="1036" y="304.9">
<tspan x="1036" y="304.9">Administrator</tspan>
</text>
</g>
<g>
<polyline style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 8; stroke: #000000" points="985.869,255 834.138,255 834.138,241 681.113,241 "/>
<polyline style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" points="693.76,236 677.76,241 693.76,246 "/>
<text font-size="12.7998" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="836.138" y="245">Triggers</text>
</g>
<g>
<polyline style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 8; stroke: #000000" points="1038,192.993 882.3,192.993 882.3,113 725.305,113 "/>
<polyline style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" points="737.953,108 721.953,113 737.953,118 "/>
<text font-size="12.7998" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="884.3" y="149.997">Defines Audit configuration in</text>
</g>
<g>
<ellipse style="fill: #ffffff" cx="103" cy="28" rx="6" ry="6"/>
<ellipse style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #ff0000" cx="103" cy="28" rx="6" ry="6"/>
<line style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #ff0000" x1="79" y1="40" x2="127" y2="40"/>
<line style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #ff0000" x1="103" y1="34" x2="103" y2="64"/>
<line style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #ff0000" x1="103" y1="64" x2="79" y2="90"/>
<line style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #ff0000" x1="103" y1="64" x2="127" y2="90"/>
<text font-size="12.8" style="fill: #ff0000;text-anchor:middle;font-family:sans-serif;font-style:normal;font-weight:700" x="103" y="113.9">
<tspan x="103" y="113.9">Customer</tspan>
</text>
</g>
<g>
<polyline style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 8; stroke: #000000" points="137.683,64 300.75,64 300.75,133.295 "/>
<polyline style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" points="295.75,120.647 300.75,136.647 305.75,120.647 "/>
<text font-size="12.7998" style="fill: #000000;text-anchor:middle;font-family:monospace;font-style:normal;font-weight:normal" x="219.217" y="61">Consumes resources</text>
</g>
<g>
<rect style="fill: #ffffff" x="27" y="258" width="102.8" height="28"/>
<rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="27" y="258" width="102.8" height="28"/>
<text font-size="16" style="fill: #000000;text-anchor:middle;font-family:sans-serif;font-style:normal;font-weight:700" x="78.4" y="277">Resources</text>
</g>
<g>
<polyline style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" points="186.828,154 78.4,154 78.4,258 "/>
<polygon style="fill: #000000" points="212,154 198,158.8 184,154 198,149.2 "/>
<polygon style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" points="212,154 198,158.8 184,154 198,149.2 "/>
<text font-size="12.7998" style="fill: #000000;text-anchor:middle;font-family:monospace;font-style:normal;font-weight:normal" x="145.2" y="151"></text>
<text font-size="12.7998" style="fill: #000000;text-anchor:end;font-family:monospace;font-style:normal;font-weight:normal" x="180" y="151"></text>
<text font-size="12.7998" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="82.4" y="254"></text>
</g>
<g>
<polyline style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 8; stroke: #000000" points="715.724,499 715.724,540 78.4,540 78.4,292.705 "/>
<polyline style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" points="83.4,305.353 78.4,289.353 73.4,305.353 "/>
<text font-size="12.7998" style="fill: #000000;text-anchor:middle;font-family:monospace;font-style:normal;font-weight:normal" x="397.062" y="537">Modifies</text>
</g>
<g>
<polyline style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 8; stroke: #000000" points="1036,309.94 1036,381 614.155,381 "/>
<polyline style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" points="626.803,376 610.803,381 626.803,386 "/>
<text font-size="12.7998" style="fill: #000000;text-anchor:middle;font-family:monospace;font-style:normal;font-weight:normal" x="821.725" y="378">Launches</text>
</g>
<g>
<rect style="fill: #ffffff" x="1082.9" y="43.1" width="88.25" height="28"/>
<rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="1082.9" y="43.1" width="88.25" height="28"/>
<text font-size="16" style="fill: #000000;text-anchor:middle;font-family:sans-serif;font-style:normal;font-weight:700" x="1127.02" y="62.1">Strategy</text>
</g>
<g>
<polyline style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 8; stroke: #000000" points="966.45,23 1020.17,23 1020.17,57.1 1075.22,57.1 "/>
<polyline style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" points="1062.57,62.1 1078.57,57.1 1062.57,52.1 "/>
<text font-size="12.7998" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="1022.17" y="37.05">uses</text>
</g>
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1146pt" height="548pt" viewBox="0 0 1146 548" version="1.1">
<defs>
<g>
<symbol overflow="visible" id="glyph0-0">
<path style="stroke:none;" d="M 0.796875 2.828125 L 0.796875 -11.28125 L 8.796875 -11.28125 L 8.796875 2.828125 Z M 1.703125 1.9375 L 7.90625 1.9375 L 7.90625 -10.390625 L 1.703125 -10.390625 Z M 1.703125 1.9375 "/>
</symbol>
<symbol overflow="visible" id="glyph0-1">
<path style="stroke:none;" d="M 8.546875 -2.125 L 3.84375 -2.125 L 3.109375 0 L 0.078125 0 L 4.40625 -11.671875 L 7.984375 -11.671875 L 12.3125 0 L 9.28125 0 Z M 4.59375 -4.296875 L 7.796875 -4.296875 L 6.203125 -8.9375 Z M 4.59375 -4.296875 "/>
</symbol>
<symbol overflow="visible" id="glyph0-2">
<path style="stroke:none;" d="M 1.25 -3.40625 L 1.25 -8.75 L 4.0625 -8.75 L 4.0625 -7.875 C 4.0625 -7.40625 4.054688 -6.8125 4.046875 -6.09375 C 4.046875 -5.375 4.046875 -4.894531 4.046875 -4.65625 C 4.046875 -3.957031 4.0625 -3.453125 4.09375 -3.140625 C 4.132812 -2.828125 4.203125 -2.601562 4.296875 -2.46875 C 4.410156 -2.28125 4.554688 -2.132812 4.734375 -2.03125 C 4.921875 -1.9375 5.132812 -1.890625 5.375 -1.890625 C 5.957031 -1.890625 6.414062 -2.113281 6.75 -2.5625 C 7.082031 -3.007812 7.25 -3.632812 7.25 -4.4375 L 7.25 -8.75 L 10.046875 -8.75 L 10.046875 0 L 7.25 0 L 7.25 -1.265625 C 6.832031 -0.753906 6.382812 -0.375 5.90625 -0.125 C 5.4375 0.113281 4.921875 0.234375 4.359375 0.234375 C 3.347656 0.234375 2.578125 -0.078125 2.046875 -0.703125 C 1.515625 -1.328125 1.25 -2.226562 1.25 -3.40625 Z M 1.25 -3.40625 "/>
</symbol>
<symbol overflow="visible" id="glyph0-3">
<path style="stroke:none;" d="M 7.296875 -7.46875 L 7.296875 -12.15625 L 10.109375 -12.15625 L 10.109375 0 L 7.296875 0 L 7.296875 -1.265625 C 6.910156 -0.753906 6.484375 -0.375 6.015625 -0.125 C 5.554688 0.113281 5.023438 0.234375 4.421875 0.234375 C 3.335938 0.234375 2.445312 -0.191406 1.75 -1.046875 C 1.0625 -1.910156 0.71875 -3.019531 0.71875 -4.375 C 0.71875 -5.71875 1.0625 -6.816406 1.75 -7.671875 C 2.445312 -8.535156 3.335938 -8.96875 4.421875 -8.96875 C 5.023438 -8.96875 5.554688 -8.84375 6.015625 -8.59375 C 6.484375 -8.351562 6.910156 -7.976562 7.296875 -7.46875 Z M 5.453125 -1.8125 C 6.054688 -1.8125 6.515625 -2.03125 6.828125 -2.46875 C 7.140625 -2.90625 7.296875 -3.539062 7.296875 -4.375 C 7.296875 -5.207031 7.140625 -5.84375 6.828125 -6.28125 C 6.515625 -6.71875 6.054688 -6.9375 5.453125 -6.9375 C 4.859375 -6.9375 4.40625 -6.71875 4.09375 -6.28125 C 3.78125 -5.84375 3.625 -5.207031 3.625 -4.375 C 3.625 -3.539062 3.78125 -2.90625 4.09375 -2.46875 C 4.40625 -2.03125 4.859375 -1.8125 5.453125 -1.8125 Z M 5.453125 -1.8125 "/>
</symbol>
<symbol overflow="visible" id="glyph0-4">
<path style="stroke:none;" d="M 1.34375 -8.75 L 4.140625 -8.75 L 4.140625 0 L 1.34375 0 Z M 1.34375 -12.15625 L 4.140625 -12.15625 L 4.140625 -9.875 L 1.34375 -9.875 Z M 1.34375 -12.15625 "/>
</symbol>
<symbol overflow="visible" id="glyph0-5">
<path style="stroke:none;" d="M 4.40625 -11.234375 L 4.40625 -8.75 L 7.28125 -8.75 L 7.28125 -6.75 L 4.40625 -6.75 L 4.40625 -3.046875 C 4.40625 -2.640625 4.484375 -2.363281 4.640625 -2.21875 C 4.804688 -2.070312 5.128906 -2 5.609375 -2 L 7.046875 -2 L 7.046875 0 L 4.640625 0 C 3.535156 0 2.753906 -0.226562 2.296875 -0.6875 C 1.835938 -1.15625 1.609375 -1.941406 1.609375 -3.046875 L 1.609375 -6.75 L 0.21875 -6.75 L 0.21875 -8.75 L 1.609375 -8.75 L 1.609375 -11.234375 Z M 4.40625 -11.234375 "/>
</symbol>
<symbol overflow="visible" id="glyph0-6">
<path style="stroke:none;" d=""/>
</symbol>
<symbol overflow="visible" id="glyph0-7">
<path style="stroke:none;" d="M 0.078125 -11.671875 L 10.828125 -11.671875 L 10.828125 -9.390625 L 6.96875 -9.390625 L 6.96875 0 L 3.953125 0 L 3.953125 -9.390625 L 0.078125 -9.390625 Z M 0.078125 -11.671875 "/>
</symbol>
<symbol overflow="visible" id="glyph0-8">
<path style="stroke:none;" d="M 10.078125 -4.40625 L 10.078125 -3.609375 L 3.546875 -3.609375 C 3.609375 -2.953125 3.84375 -2.457031 4.25 -2.125 C 4.65625 -1.800781 5.222656 -1.640625 5.953125 -1.640625 C 6.546875 -1.640625 7.148438 -1.722656 7.765625 -1.890625 C 8.378906 -2.066406 9.015625 -2.332031 9.671875 -2.6875 L 9.671875 -0.53125 C 9.003906 -0.28125 8.335938 -0.09375 7.671875 0.03125 C 7.015625 0.164062 6.359375 0.234375 5.703125 0.234375 C 4.117188 0.234375 2.882812 -0.164062 2 -0.96875 C 1.125 -1.78125 0.6875 -2.914062 0.6875 -4.375 C 0.6875 -5.800781 1.117188 -6.921875 1.984375 -7.734375 C 2.847656 -8.554688 4.035156 -8.96875 5.546875 -8.96875 C 6.921875 -8.96875 8.019531 -8.550781 8.84375 -7.71875 C 9.664062 -6.894531 10.078125 -5.789062 10.078125 -4.40625 Z M 7.203125 -5.328125 C 7.203125 -5.859375 7.046875 -6.285156 6.734375 -6.609375 C 6.429688 -6.941406 6.03125 -7.109375 5.53125 -7.109375 C 4.988281 -7.109375 4.546875 -6.953125 4.203125 -6.640625 C 3.867188 -6.335938 3.660156 -5.898438 3.578125 -5.328125 Z M 7.203125 -5.328125 "/>
</symbol>
<symbol overflow="visible" id="glyph0-9">
<path style="stroke:none;" d="M 9.453125 -7.296875 C 9.804688 -7.835938 10.226562 -8.25 10.71875 -8.53125 C 11.207031 -8.820312 11.742188 -8.96875 12.328125 -8.96875 C 13.328125 -8.96875 14.085938 -8.65625 14.609375 -8.03125 C 15.140625 -7.414062 15.40625 -6.515625 15.40625 -5.328125 L 15.40625 0 L 12.59375 0 L 12.59375 -4.5625 C 12.601562 -4.632812 12.609375 -4.707031 12.609375 -4.78125 C 12.609375 -4.851562 12.609375 -4.957031 12.609375 -5.09375 C 12.609375 -5.707031 12.515625 -6.15625 12.328125 -6.4375 C 12.148438 -6.71875 11.859375 -6.859375 11.453125 -6.859375 C 10.921875 -6.859375 10.507812 -6.640625 10.21875 -6.203125 C 9.9375 -5.765625 9.789062 -5.128906 9.78125 -4.296875 L 9.78125 0 L 6.96875 0 L 6.96875 -4.5625 C 6.96875 -5.53125 6.882812 -6.15625 6.71875 -6.4375 C 6.550781 -6.71875 6.253906 -6.859375 5.828125 -6.859375 C 5.285156 -6.859375 4.867188 -6.632812 4.578125 -6.1875 C 4.285156 -5.75 4.140625 -5.125 4.140625 -4.3125 L 4.140625 0 L 1.328125 0 L 1.328125 -8.75 L 4.140625 -8.75 L 4.140625 -7.46875 C 4.484375 -7.96875 4.878906 -8.34375 5.328125 -8.59375 C 5.773438 -8.84375 6.265625 -8.96875 6.796875 -8.96875 C 7.398438 -8.96875 7.929688 -8.820312 8.390625 -8.53125 C 8.859375 -8.238281 9.210938 -7.828125 9.453125 -7.296875 Z M 9.453125 -7.296875 "/>
</symbol>
<symbol overflow="visible" id="glyph0-10">
<path style="stroke:none;" d="M 4.140625 -1.265625 L 4.140625 3.328125 L 1.34375 3.328125 L 1.34375 -8.75 L 4.140625 -8.75 L 4.140625 -7.46875 C 4.523438 -7.976562 4.953125 -8.351562 5.421875 -8.59375 C 5.890625 -8.84375 6.429688 -8.96875 7.046875 -8.96875 C 8.117188 -8.96875 9 -8.535156 9.6875 -7.671875 C 10.382812 -6.816406 10.734375 -5.71875 10.734375 -4.375 C 10.734375 -3.019531 10.382812 -1.910156 9.6875 -1.046875 C 9 -0.191406 8.117188 0.234375 7.046875 0.234375 C 6.429688 0.234375 5.890625 0.113281 5.421875 -0.125 C 4.953125 -0.375 4.523438 -0.753906 4.140625 -1.265625 Z M 6 -6.9375 C 5.40625 -6.9375 4.945312 -6.710938 4.625 -6.265625 C 4.300781 -5.828125 4.140625 -5.195312 4.140625 -4.375 C 4.140625 -3.539062 4.300781 -2.90625 4.625 -2.46875 C 4.945312 -2.03125 5.40625 -1.8125 6 -1.8125 C 6.601562 -1.8125 7.0625 -2.03125 7.375 -2.46875 C 7.6875 -2.90625 7.84375 -3.539062 7.84375 -4.375 C 7.84375 -5.207031 7.6875 -5.84375 7.375 -6.28125 C 7.0625 -6.71875 6.601562 -6.9375 6 -6.9375 Z M 6 -6.9375 "/>
</symbol>
<symbol overflow="visible" id="glyph0-11">
<path style="stroke:none;" d="M 1.34375 -12.15625 L 4.140625 -12.15625 L 4.140625 0 L 1.34375 0 Z M 1.34375 -12.15625 "/>
</symbol>
<symbol overflow="visible" id="glyph0-12">
<path style="stroke:none;" d="M 5.265625 -3.9375 C 4.679688 -3.9375 4.242188 -3.835938 3.953125 -3.640625 C 3.660156 -3.441406 3.515625 -3.148438 3.515625 -2.765625 C 3.515625 -2.410156 3.628906 -2.132812 3.859375 -1.9375 C 4.097656 -1.738281 4.429688 -1.640625 4.859375 -1.640625 C 5.378906 -1.640625 5.816406 -1.828125 6.171875 -2.203125 C 6.535156 -2.578125 6.71875 -3.050781 6.71875 -3.625 L 6.71875 -3.9375 Z M 9.546875 -5 L 9.546875 0 L 6.71875 0 L 6.71875 -1.296875 C 6.34375 -0.765625 5.921875 -0.375 5.453125 -0.125 C 4.984375 0.113281 4.414062 0.234375 3.75 0.234375 C 2.84375 0.234375 2.101562 -0.03125 1.53125 -0.5625 C 0.96875 -1.09375 0.6875 -1.78125 0.6875 -2.625 C 0.6875 -3.65625 1.039062 -4.410156 1.75 -4.890625 C 2.457031 -5.367188 3.566406 -5.609375 5.078125 -5.609375 L 6.71875 -5.609375 L 6.71875 -5.828125 C 6.71875 -6.265625 6.539062 -6.585938 6.1875 -6.796875 C 5.84375 -7.003906 5.300781 -7.109375 4.5625 -7.109375 C 3.96875 -7.109375 3.410156 -7.046875 2.890625 -6.921875 C 2.378906 -6.804688 1.898438 -6.628906 1.453125 -6.390625 L 1.453125 -8.515625 C 2.054688 -8.660156 2.660156 -8.769531 3.265625 -8.84375 C 3.867188 -8.925781 4.472656 -8.96875 5.078125 -8.96875 C 6.648438 -8.96875 7.785156 -8.65625 8.484375 -8.03125 C 9.191406 -7.40625 9.546875 -6.394531 9.546875 -5 Z M 9.546875 -5 "/>
</symbol>
<symbol overflow="visible" id="glyph0-13">
<path style="stroke:none;" d="M 6.796875 -9.703125 C 5.878906 -9.703125 5.164062 -9.363281 4.65625 -8.6875 C 4.15625 -8.007812 3.90625 -7.054688 3.90625 -5.828125 C 3.90625 -4.597656 4.15625 -3.644531 4.65625 -2.96875 C 5.164062 -2.289062 5.878906 -1.953125 6.796875 -1.953125 C 7.722656 -1.953125 8.4375 -2.289062 8.9375 -2.96875 C 9.445312 -3.644531 9.703125 -4.597656 9.703125 -5.828125 C 9.703125 -7.054688 9.445312 -8.007812 8.9375 -8.6875 C 8.4375 -9.363281 7.722656 -9.703125 6.796875 -9.703125 Z M 6.796875 -11.875 C 8.671875 -11.875 10.140625 -11.335938 11.203125 -10.265625 C 12.265625 -9.191406 12.796875 -7.710938 12.796875 -5.828125 C 12.796875 -3.941406 12.265625 -2.457031 11.203125 -1.375 C 10.140625 -0.300781 8.671875 0.234375 6.796875 0.234375 C 4.929688 0.234375 3.460938 -0.300781 2.390625 -1.375 C 1.328125 -2.457031 0.796875 -3.941406 0.796875 -5.828125 C 0.796875 -7.710938 1.328125 -9.191406 2.390625 -10.265625 C 3.460938 -11.335938 4.929688 -11.875 6.796875 -11.875 Z M 6.796875 -11.875 "/>
</symbol>
<symbol overflow="visible" id="glyph0-14">
<path style="stroke:none;" d="M 10.140625 -5.328125 L 10.140625 0 L 7.328125 0 L 7.328125 -4.078125 C 7.328125 -4.835938 7.3125 -5.359375 7.28125 -5.640625 C 7.25 -5.929688 7.191406 -6.144531 7.109375 -6.28125 C 6.992188 -6.457031 6.84375 -6.597656 6.65625 -6.703125 C 6.46875 -6.804688 6.253906 -6.859375 6.015625 -6.859375 C 5.429688 -6.859375 4.972656 -6.628906 4.640625 -6.171875 C 4.304688 -5.722656 4.140625 -5.101562 4.140625 -4.3125 L 4.140625 0 L 1.34375 0 L 1.34375 -8.75 L 4.140625 -8.75 L 4.140625 -7.46875 C 4.566406 -7.976562 5.015625 -8.351562 5.484375 -8.59375 C 5.960938 -8.84375 6.488281 -8.96875 7.0625 -8.96875 C 8.070312 -8.96875 8.835938 -8.65625 9.359375 -8.03125 C 9.878906 -7.414062 10.140625 -6.515625 10.140625 -5.328125 Z M 10.140625 -5.328125 "/>
</symbol>
<symbol overflow="visible" id="glyph0-15">
<path style="stroke:none;" d="M 9.59375 -11.296875 L 9.59375 -8.828125 C 8.945312 -9.117188 8.316406 -9.335938 7.703125 -9.484375 C 7.097656 -9.628906 6.523438 -9.703125 5.984375 -9.703125 C 5.265625 -9.703125 4.734375 -9.601562 4.390625 -9.40625 C 4.046875 -9.207031 3.875 -8.898438 3.875 -8.484375 C 3.875 -8.171875 3.988281 -7.925781 4.21875 -7.75 C 4.457031 -7.570312 4.878906 -7.421875 5.484375 -7.296875 L 6.765625 -7.046875 C 8.066406 -6.785156 8.988281 -6.390625 9.53125 -5.859375 C 10.082031 -5.328125 10.359375 -4.570312 10.359375 -3.59375 C 10.359375 -2.300781 9.972656 -1.335938 9.203125 -0.703125 C 8.441406 -0.078125 7.28125 0.234375 5.71875 0.234375 C 4.976562 0.234375 4.234375 0.160156 3.484375 0.015625 C 2.742188 -0.128906 2 -0.335938 1.25 -0.609375 L 1.25 -3.15625 C 2 -2.757812 2.71875 -2.457031 3.40625 -2.25 C 4.101562 -2.050781 4.773438 -1.953125 5.421875 -1.953125 C 6.078125 -1.953125 6.578125 -2.0625 6.921875 -2.28125 C 7.273438 -2.5 7.453125 -2.8125 7.453125 -3.21875 C 7.453125 -3.582031 7.332031 -3.863281 7.09375 -4.0625 C 6.863281 -4.257812 6.394531 -4.4375 5.6875 -4.59375 L 4.515625 -4.859375 C 3.347656 -5.109375 2.492188 -5.503906 1.953125 -6.046875 C 1.421875 -6.597656 1.15625 -7.335938 1.15625 -8.265625 C 1.15625 -9.421875 1.53125 -10.3125 2.28125 -10.9375 C 3.03125 -11.5625 4.109375 -11.875 5.515625 -11.875 C 6.148438 -11.875 6.804688 -11.828125 7.484375 -11.734375 C 8.160156 -11.640625 8.863281 -11.492188 9.59375 -11.296875 Z M 9.59375 -11.296875 "/>
</symbol>
<symbol overflow="visible" id="glyph0-16">
<path style="stroke:none;" d="M 8.421875 -8.484375 L 8.421875 -6.203125 C 8.035156 -6.460938 7.648438 -6.65625 7.265625 -6.78125 C 6.890625 -6.90625 6.492188 -6.96875 6.078125 -6.96875 C 5.296875 -6.96875 4.6875 -6.738281 4.25 -6.28125 C 3.820312 -5.820312 3.609375 -5.1875 3.609375 -4.375 C 3.609375 -3.550781 3.820312 -2.910156 4.25 -2.453125 C 4.6875 -2.003906 5.296875 -1.78125 6.078125 -1.78125 C 6.515625 -1.78125 6.929688 -1.84375 7.328125 -1.96875 C 7.722656 -2.101562 8.085938 -2.296875 8.421875 -2.546875 L 8.421875 -0.265625 C 7.984375 -0.0976562 7.535156 0.0234375 7.078125 0.109375 C 6.628906 0.191406 6.179688 0.234375 5.734375 0.234375 C 4.148438 0.234375 2.910156 -0.171875 2.015625 -0.984375 C 1.128906 -1.796875 0.6875 -2.925781 0.6875 -4.375 C 0.6875 -5.8125 1.128906 -6.9375 2.015625 -7.75 C 2.910156 -8.5625 4.148438 -8.96875 5.734375 -8.96875 C 6.191406 -8.96875 6.640625 -8.925781 7.078125 -8.84375 C 7.523438 -8.757812 7.972656 -8.640625 8.421875 -8.484375 Z M 8.421875 -8.484375 "/>
</symbol>
<symbol overflow="visible" id="glyph0-17">
<path style="stroke:none;" d="M 1.34375 -12.15625 L 4.140625 -12.15625 L 4.140625 -5.546875 L 7.359375 -8.75 L 10.609375 -8.75 L 6.34375 -4.734375 L 10.953125 0 L 7.5625 0 L 4.140625 -3.65625 L 4.140625 0 L 1.34375 0 Z M 1.34375 -12.15625 "/>
</symbol>
<symbol overflow="visible" id="glyph0-18">
<path style="stroke:none;" d="M 10.71875 -0.640625 C 10.164062 -0.359375 9.585938 -0.144531 8.984375 0 C 8.390625 0.15625 7.769531 0.234375 7.125 0.234375 C 5.175781 0.234375 3.632812 -0.304688 2.5 -1.390625 C 1.363281 -2.484375 0.796875 -3.960938 0.796875 -5.828125 C 0.796875 -7.691406 1.363281 -9.164062 2.5 -10.25 C 3.632812 -11.332031 5.175781 -11.875 7.125 -11.875 C 7.769531 -11.875 8.390625 -11.800781 8.984375 -11.65625 C 9.585938 -11.507812 10.164062 -11.296875 10.71875 -11.015625 L 10.71875 -8.59375 C 10.164062 -8.976562 9.617188 -9.257812 9.078125 -9.4375 C 8.535156 -9.613281 7.960938 -9.703125 7.359375 -9.703125 C 6.285156 -9.703125 5.441406 -9.359375 4.828125 -8.671875 C 4.210938 -7.984375 3.90625 -7.035156 3.90625 -5.828125 C 3.90625 -4.617188 4.210938 -3.671875 4.828125 -2.984375 C 5.441406 -2.296875 6.285156 -1.953125 7.359375 -1.953125 C 7.960938 -1.953125 8.535156 -2.039062 9.078125 -2.21875 C 9.617188 -2.394531 10.164062 -2.675781 10.71875 -3.0625 Z M 10.71875 -0.640625 "/>
</symbol>
<symbol overflow="visible" id="glyph0-19">
<path style="stroke:none;" d="M 8.1875 -8.484375 L 8.1875 -6.359375 C 7.582031 -6.609375 7 -6.796875 6.4375 -6.921875 C 5.882812 -7.046875 5.363281 -7.109375 4.875 -7.109375 C 4.34375 -7.109375 3.945312 -7.039062 3.6875 -6.90625 C 3.425781 -6.769531 3.296875 -6.566406 3.296875 -6.296875 C 3.296875 -6.066406 3.394531 -5.890625 3.59375 -5.765625 C 3.789062 -5.648438 4.140625 -5.566406 4.640625 -5.515625 L 5.140625 -5.4375 C 6.566406 -5.257812 7.523438 -4.960938 8.015625 -4.546875 C 8.515625 -4.128906 8.765625 -3.472656 8.765625 -2.578125 C 8.765625 -1.648438 8.421875 -0.945312 7.734375 -0.46875 C 7.046875 0 6.019531 0.234375 4.65625 0.234375 C 4.082031 0.234375 3.484375 0.1875 2.859375 0.09375 C 2.242188 0 1.613281 -0.140625 0.96875 -0.328125 L 0.96875 -2.453125 C 1.519531 -2.179688 2.085938 -1.976562 2.671875 -1.84375 C 3.265625 -1.707031 3.863281 -1.640625 4.46875 -1.640625 C 5.007812 -1.640625 5.414062 -1.710938 5.6875 -1.859375 C 5.96875 -2.015625 6.109375 -2.238281 6.109375 -2.53125 C 6.109375 -2.78125 6.015625 -2.96875 5.828125 -3.09375 C 5.640625 -3.21875 5.257812 -3.3125 4.6875 -3.375 L 4.203125 -3.4375 C 2.953125 -3.59375 2.078125 -3.878906 1.578125 -4.296875 C 1.078125 -4.722656 0.828125 -5.367188 0.828125 -6.234375 C 0.828125 -7.160156 1.144531 -7.847656 1.78125 -8.296875 C 2.414062 -8.742188 3.390625 -8.96875 4.703125 -8.96875 C 5.222656 -8.96875 5.765625 -8.925781 6.328125 -8.84375 C 6.898438 -8.769531 7.519531 -8.648438 8.1875 -8.484375 Z M 8.1875 -8.484375 "/>
</symbol>
<symbol overflow="visible" id="glyph0-20">
<path style="stroke:none;" d="M 7.84375 -6.375 C 7.601562 -6.488281 7.359375 -6.570312 7.109375 -6.625 C 6.867188 -6.675781 6.628906 -6.703125 6.390625 -6.703125 C 5.671875 -6.703125 5.113281 -6.472656 4.71875 -6.015625 C 4.332031 -5.554688 4.140625 -4.894531 4.140625 -4.03125 L 4.140625 0 L 1.34375 0 L 1.34375 -8.75 L 4.140625 -8.75 L 4.140625 -7.3125 C 4.503906 -7.882812 4.914062 -8.300781 5.375 -8.5625 C 5.84375 -8.832031 6.40625 -8.96875 7.0625 -8.96875 C 7.15625 -8.96875 7.253906 -8.960938 7.359375 -8.953125 C 7.472656 -8.941406 7.632812 -8.925781 7.84375 -8.90625 Z M 7.84375 -6.375 "/>
</symbol>
<symbol overflow="visible" id="glyph0-21">
<path style="stroke:none;" d="M 11.953125 -0.875 C 11.203125 -0.507812 10.421875 -0.234375 9.609375 -0.046875 C 8.804688 0.140625 7.976562 0.234375 7.125 0.234375 C 5.175781 0.234375 3.632812 -0.304688 2.5 -1.390625 C 1.363281 -2.484375 0.796875 -3.960938 0.796875 -5.828125 C 0.796875 -7.703125 1.375 -9.175781 2.53125 -10.25 C 3.6875 -11.332031 5.269531 -11.875 7.28125 -11.875 C 8.0625 -11.875 8.804688 -11.800781 9.515625 -11.65625 C 10.222656 -11.507812 10.894531 -11.296875 11.53125 -11.015625 L 11.53125 -8.59375 C 10.875 -8.96875 10.222656 -9.242188 9.578125 -9.421875 C 8.941406 -9.609375 8.300781 -9.703125 7.65625 -9.703125 C 6.457031 -9.703125 5.53125 -9.363281 4.875 -8.6875 C 4.226562 -8.019531 3.90625 -7.066406 3.90625 -5.828125 C 3.90625 -4.585938 4.21875 -3.628906 4.84375 -2.953125 C 5.46875 -2.285156 6.359375 -1.953125 7.515625 -1.953125 C 7.828125 -1.953125 8.113281 -1.972656 8.375 -2.015625 C 8.644531 -2.054688 8.890625 -2.117188 9.109375 -2.203125 L 9.109375 -4.46875 L 7.265625 -4.46875 L 7.265625 -6.484375 L 11.953125 -6.484375 Z M 11.953125 -0.875 "/>
</symbol>
<symbol overflow="visible" id="glyph0-22">
<path style="stroke:none;" d="M 5.515625 -6.96875 C 4.890625 -6.96875 4.414062 -6.742188 4.09375 -6.296875 C 3.769531 -5.847656 3.609375 -5.207031 3.609375 -4.375 C 3.609375 -3.53125 3.769531 -2.882812 4.09375 -2.4375 C 4.414062 -2 4.890625 -1.78125 5.515625 -1.78125 C 6.117188 -1.78125 6.582031 -2 6.90625 -2.4375 C 7.226562 -2.882812 7.390625 -3.53125 7.390625 -4.375 C 7.390625 -5.207031 7.226562 -5.847656 6.90625 -6.296875 C 6.582031 -6.742188 6.117188 -6.96875 5.515625 -6.96875 Z M 5.515625 -8.96875 C 7.015625 -8.96875 8.1875 -8.5625 9.03125 -7.75 C 9.882812 -6.9375 10.3125 -5.8125 10.3125 -4.375 C 10.3125 -2.9375 9.882812 -1.804688 9.03125 -0.984375 C 8.1875 -0.171875 7.015625 0.234375 5.515625 0.234375 C 4.003906 0.234375 2.820312 -0.171875 1.96875 -0.984375 C 1.113281 -1.804688 0.6875 -2.9375 0.6875 -4.375 C 0.6875 -5.8125 1.113281 -6.9375 1.96875 -7.75 C 2.820312 -8.5625 4.003906 -8.96875 5.515625 -8.96875 Z M 5.515625 -8.96875 "/>
</symbol>
<symbol overflow="visible" id="glyph0-23">
<path style="stroke:none;" d="M 1.46875 -11.671875 L 6.46875 -11.671875 C 7.945312 -11.671875 9.082031 -11.335938 9.875 -10.671875 C 10.675781 -10.015625 11.078125 -9.078125 11.078125 -7.859375 C 11.078125 -6.640625 10.675781 -5.695312 9.875 -5.03125 C 9.082031 -4.375 7.945312 -4.046875 6.46875 -4.046875 L 4.484375 -4.046875 L 4.484375 0 L 1.46875 0 Z M 4.484375 -9.484375 L 4.484375 -6.234375 L 6.140625 -6.234375 C 6.722656 -6.234375 7.171875 -6.375 7.484375 -6.65625 C 7.804688 -6.9375 7.96875 -7.335938 7.96875 -7.859375 C 7.96875 -8.378906 7.804688 -8.78125 7.484375 -9.0625 C 7.171875 -9.34375 6.722656 -9.484375 6.140625 -9.484375 Z M 4.484375 -9.484375 "/>
</symbol>
<symbol overflow="visible" id="glyph0-24">
<path style="stroke:none;" d="M 5.75 -6.5 C 6.375 -6.5 6.820312 -6.613281 7.09375 -6.84375 C 7.375 -7.082031 7.515625 -7.46875 7.515625 -8 C 7.515625 -8.53125 7.375 -8.910156 7.09375 -9.140625 C 6.820312 -9.367188 6.375 -9.484375 5.75 -9.484375 L 4.484375 -9.484375 L 4.484375 -6.5 Z M 4.484375 -4.421875 L 4.484375 0 L 1.46875 0 L 1.46875 -11.671875 L 6.0625 -11.671875 C 7.601562 -11.671875 8.726562 -11.410156 9.4375 -10.890625 C 10.15625 -10.378906 10.515625 -9.566406 10.515625 -8.453125 C 10.515625 -7.679688 10.328125 -7.046875 9.953125 -6.546875 C 9.585938 -6.054688 9.03125 -5.691406 8.28125 -5.453125 C 8.6875 -5.359375 9.050781 -5.144531 9.375 -4.8125 C 9.707031 -4.488281 10.039062 -3.988281 10.375 -3.3125 L 12 0 L 8.796875 0 L 7.375 -2.90625 C 7.09375 -3.488281 6.800781 -3.882812 6.5 -4.09375 C 6.207031 -4.3125 5.816406 -4.421875 5.328125 -4.421875 Z M 4.484375 -4.421875 "/>
</symbol>
<symbol overflow="visible" id="glyph0-25">
<path style="stroke:none;" d="M 7.296875 -1.484375 C 6.910156 -0.972656 6.484375 -0.597656 6.015625 -0.359375 C 5.554688 -0.117188 5.023438 0 4.421875 0 C 3.347656 0 2.460938 -0.421875 1.765625 -1.265625 C 1.066406 -2.109375 0.71875 -3.179688 0.71875 -4.484375 C 0.71875 -5.785156 1.066406 -6.851562 1.765625 -7.6875 C 2.460938 -8.53125 3.347656 -8.953125 4.421875 -8.953125 C 5.023438 -8.953125 5.554688 -8.832031 6.015625 -8.59375 C 6.484375 -8.351562 6.910156 -7.972656 7.296875 -7.453125 L 7.296875 -8.75 L 10.109375 -8.75 L 10.109375 -0.890625 C 10.109375 0.523438 9.664062 1.601562 8.78125 2.34375 C 7.894531 3.082031 6.609375 3.453125 4.921875 3.453125 C 4.367188 3.453125 3.835938 3.410156 3.328125 3.328125 C 2.816406 3.242188 2.304688 3.117188 1.796875 2.953125 L 1.796875 0.765625 C 2.285156 1.046875 2.765625 1.253906 3.234375 1.390625 C 3.703125 1.535156 4.171875 1.609375 4.640625 1.609375 C 5.554688 1.609375 6.226562 1.40625 6.65625 1 C 7.082031 0.601562 7.296875 -0.0234375 7.296875 -0.890625 Z M 5.453125 -6.9375 C 4.878906 -6.9375 4.429688 -6.722656 4.109375 -6.296875 C 3.785156 -5.867188 3.625 -5.265625 3.625 -4.484375 C 3.625 -3.679688 3.78125 -3.070312 4.09375 -2.65625 C 4.40625 -2.238281 4.859375 -2.03125 5.453125 -2.03125 C 6.035156 -2.03125 6.488281 -2.242188 6.8125 -2.671875 C 7.132812 -3.097656 7.296875 -3.703125 7.296875 -4.484375 C 7.296875 -5.265625 7.132812 -5.867188 6.8125 -6.296875 C 6.488281 -6.722656 6.035156 -6.9375 5.453125 -6.9375 Z M 5.453125 -6.9375 "/>
</symbol>
<symbol overflow="visible" id="glyph0-26">
<path style="stroke:none;" d="M 0.203125 -8.75 L 3 -8.75 L 5.34375 -2.8125 L 7.34375 -8.75 L 10.140625 -8.75 L 6.46875 0.828125 C 6.09375 1.804688 5.660156 2.488281 5.171875 2.875 C 4.679688 3.257812 4.03125 3.453125 3.21875 3.453125 L 1.609375 3.453125 L 1.609375 1.625 L 2.484375 1.625 C 2.953125 1.625 3.296875 1.546875 3.515625 1.390625 C 3.734375 1.242188 3.898438 0.972656 4.015625 0.578125 L 4.09375 0.34375 Z M 0.203125 -8.75 "/>
</symbol>
<symbol overflow="visible" id="glyph0-27">
<path style="stroke:none;" d="M 1.46875 -11.671875 L 9.59375 -11.671875 L 9.59375 -9.390625 L 4.484375 -9.390625 L 4.484375 -7.21875 L 9.28125 -7.21875 L 9.28125 -4.953125 L 4.484375 -4.953125 L 4.484375 -2.28125 L 9.765625 -2.28125 L 9.765625 0 L 1.46875 0 Z M 1.46875 -11.671875 "/>
</symbol>
<symbol overflow="visible" id="glyph0-28">
<path style="stroke:none;" d="M 7.109375 -12.15625 L 7.109375 -10.328125 L 5.5625 -10.328125 C 5.164062 -10.328125 4.890625 -10.253906 4.734375 -10.109375 C 4.578125 -9.960938 4.5 -9.710938 4.5 -9.359375 L 4.5 -8.75 L 7.703125 -8.75 L 7.703125 -9.359375 C 7.703125 -10.316406 7.96875 -11.019531 8.5 -11.46875 C 9.03125 -11.925781 9.851562 -12.15625 10.96875 -12.15625 L 13.109375 -12.15625 L 13.109375 -10.328125 L 11.5625 -10.328125 C 11.164062 -10.328125 10.894531 -10.253906 10.75 -10.109375 C 10.59375 -9.960938 10.515625 -9.710938 10.515625 -9.359375 L 10.515625 -8.75 L 16.5 -8.75 L 16.5 0 L 13.6875 0 L 13.6875 -6.75 L 10.515625 -6.75 L 10.515625 0 L 7.703125 0 L 7.703125 -6.75 L 4.5 -6.75 L 4.5 0 L 1.703125 0 L 1.703125 -6.75 L 0.3125 -6.75 L 0.3125 -8.75 L 1.703125 -8.75 L 1.703125 -9.359375 C 1.703125 -10.316406 1.96875 -11.019531 2.5 -11.46875 C 3.03125 -11.925781 3.851562 -12.15625 4.96875 -12.15625 Z M 13.6875 -12.15625 L 16.5 -12.15625 L 16.5 -9.875 L 13.6875 -9.875 Z M 13.6875 -12.15625 "/>
</symbol>
<symbol overflow="visible" id="glyph0-29">
<path style="stroke:none;" d="M 1.46875 -11.671875 L 4.484375 -11.671875 L 4.484375 0 L 1.46875 0 Z M 1.46875 -11.671875 "/>
</symbol>
<symbol overflow="visible" id="glyph1-0">
<path style="stroke:none;" d="M 0.65625 2.296875 L 0.65625 -9.171875 L 7.15625 -9.171875 L 7.15625 2.296875 Z M 1.390625 1.578125 L 6.4375 1.578125 L 6.4375 -8.4375 L 1.390625 -8.4375 Z M 1.390625 1.578125 "/>
</symbol>
<symbol overflow="visible" id="glyph1-1">
<path style="stroke:none;" d="M 3.90625 -8.34375 L 2.5625 -3.5 L 5.265625 -3.5 Z M 3.140625 -9.484375 L 4.6875 -9.484375 L 7.59375 0 L 6.265625 0 L 5.5625 -2.46875 L 2.25 -2.46875 L 1.5625 0 L 0.234375 0 Z M 3.140625 -9.484375 "/>
</symbol>
<symbol overflow="visible" id="glyph1-2">
<path style="stroke:none;" d="M 2.375 -0.890625 L 2.375 2.703125 L 1.203125 2.703125 L 1.203125 -7.109375 L 2.375 -7.109375 L 2.375 -6.203125 C 2.570312 -6.554688 2.832031 -6.820312 3.15625 -7 C 3.476562 -7.1875 3.851562 -7.28125 4.28125 -7.28125 C 5.132812 -7.28125 5.804688 -6.945312 6.296875 -6.28125 C 6.785156 -5.613281 7.03125 -4.691406 7.03125 -3.515625 C 7.03125 -2.367188 6.785156 -1.460938 6.296875 -0.796875 C 5.804688 -0.140625 5.132812 0.1875 4.28125 0.1875 C 3.84375 0.1875 3.460938 0.09375 3.140625 -0.09375 C 2.816406 -0.28125 2.5625 -0.546875 2.375 -0.890625 Z M 5.8125 -3.546875 C 5.8125 -4.453125 5.664062 -5.132812 5.375 -5.59375 C 5.09375 -6.0625 4.671875 -6.296875 4.109375 -6.296875 C 3.535156 -6.296875 3.101562 -6.0625 2.8125 -5.59375 C 2.519531 -5.132812 2.375 -4.453125 2.375 -3.546875 C 2.375 -2.648438 2.519531 -1.96875 2.8125 -1.5 C 3.101562 -1.039062 3.535156 -0.8125 4.109375 -0.8125 C 4.671875 -0.8125 5.09375 -1.039062 5.375 -1.5 C 5.664062 -1.957031 5.8125 -2.640625 5.8125 -3.546875 Z M 5.8125 -3.546875 "/>
</symbol>
<symbol overflow="visible" id="glyph1-3">
<path style="stroke:none;" d="M 4.0625 -2.578125 C 4.0625 -2.054688 4.15625 -1.660156 4.34375 -1.390625 C 4.539062 -1.117188 4.828125 -0.984375 5.203125 -0.984375 L 6.5625 -0.984375 L 6.5625 0 L 5.078125 0 C 4.378906 0 3.835938 -0.222656 3.453125 -0.671875 C 3.078125 -1.117188 2.890625 -1.753906 2.890625 -2.578125 L 2.890625 -9.03125 L 1.015625 -9.03125 L 1.015625 -9.953125 L 4.0625 -9.953125 Z M 4.0625 -2.578125 "/>
</symbol>
<symbol overflow="visible" id="glyph1-4">
<path style="stroke:none;" d="M 1.625 -7.109375 L 4.609375 -7.109375 L 4.609375 -0.90625 L 6.9375 -0.90625 L 6.9375 0 L 1.125 0 L 1.125 -0.90625 L 3.453125 -0.90625 L 3.453125 -6.203125 L 1.625 -6.203125 Z M 3.453125 -9.875 L 4.609375 -9.875 L 4.609375 -8.390625 L 3.453125 -8.390625 Z M 3.453125 -9.875 "/>
</symbol>
<symbol overflow="visible" id="glyph1-5">
<path style="stroke:none;" d="M 7.0625 -3.84375 L 7.0625 -3.28125 L 2 -3.28125 L 2 -3.234375 C 2 -2.460938 2.203125 -1.863281 2.609375 -1.4375 C 3.015625 -1.019531 3.582031 -0.8125 4.3125 -0.8125 C 4.6875 -0.8125 5.078125 -0.867188 5.484375 -0.984375 C 5.890625 -1.097656 6.320312 -1.28125 6.78125 -1.53125 L 6.78125 -0.359375 C 6.34375 -0.179688 5.914062 -0.046875 5.5 0.046875 C 5.082031 0.140625 4.679688 0.1875 4.296875 0.1875 C 3.191406 0.1875 2.328125 -0.140625 1.703125 -0.796875 C 1.085938 -1.460938 0.78125 -2.378906 0.78125 -3.546875 C 0.78125 -4.679688 1.082031 -5.585938 1.6875 -6.265625 C 2.300781 -6.941406 3.113281 -7.28125 4.125 -7.28125 C 5.03125 -7.28125 5.742188 -6.972656 6.265625 -6.359375 C 6.796875 -5.742188 7.0625 -4.90625 7.0625 -3.84375 Z M 5.890625 -4.1875 C 5.867188 -4.875 5.703125 -5.394531 5.390625 -5.75 C 5.085938 -6.113281 4.648438 -6.296875 4.078125 -6.296875 C 3.515625 -6.296875 3.050781 -6.109375 2.6875 -5.734375 C 2.320312 -5.359375 2.109375 -4.84375 2.046875 -4.1875 Z M 5.890625 -4.1875 "/>
</symbol>
<symbol overflow="visible" id="glyph1-6">
<path style="stroke:none;" d="M 6.171875 -6.859375 L 6.171875 -5.71875 C 5.835938 -5.914062 5.5 -6.0625 5.15625 -6.15625 C 4.820312 -6.25 4.476562 -6.296875 4.125 -6.296875 C 3.601562 -6.296875 3.210938 -6.210938 2.953125 -6.046875 C 2.691406 -5.878906 2.5625 -5.617188 2.5625 -5.265625 C 2.5625 -4.941406 2.65625 -4.703125 2.84375 -4.546875 C 3.039062 -4.390625 3.523438 -4.238281 4.296875 -4.09375 L 4.78125 -4 C 5.351562 -3.894531 5.785156 -3.675781 6.078125 -3.34375 C 6.378906 -3.007812 6.53125 -2.582031 6.53125 -2.0625 C 6.53125 -1.351562 6.28125 -0.800781 5.78125 -0.40625 C 5.289062 -0.0078125 4.597656 0.1875 3.703125 0.1875 C 3.359375 0.1875 2.992188 0.148438 2.609375 0.078125 C 2.222656 0.00390625 1.804688 -0.109375 1.359375 -0.265625 L 1.359375 -1.46875 C 1.785156 -1.238281 2.195312 -1.066406 2.59375 -0.953125 C 3 -0.847656 3.378906 -0.796875 3.734375 -0.796875 C 4.242188 -0.796875 4.640625 -0.898438 4.921875 -1.109375 C 5.210938 -1.316406 5.359375 -1.609375 5.359375 -1.984375 C 5.359375 -2.523438 4.835938 -2.898438 3.796875 -3.109375 L 3.75 -3.125 L 3.3125 -3.21875 C 2.632812 -3.34375 2.140625 -3.5625 1.828125 -3.875 C 1.523438 -4.1875 1.375 -4.609375 1.375 -5.140625 C 1.375 -5.828125 1.601562 -6.351562 2.0625 -6.71875 C 2.53125 -7.09375 3.191406 -7.28125 4.046875 -7.28125 C 4.421875 -7.28125 4.785156 -7.242188 5.140625 -7.171875 C 5.492188 -7.109375 5.835938 -7.003906 6.171875 -6.859375 Z M 6.171875 -6.859375 "/>
</symbol>
<symbol overflow="visible" id="glyph1-7">
<path style="stroke:none;" d=""/>
</symbol>
<symbol overflow="visible" id="glyph1-8">
<path style="stroke:none;" d="M 3.890625 -9.125 L 3.890625 -7.109375 L 6.546875 -7.109375 L 6.546875 -6.203125 L 3.890625 -6.203125 L 3.890625 -2.34375 C 3.890625 -1.820312 3.988281 -1.457031 4.1875 -1.25 C 4.394531 -1.039062 4.742188 -0.9375 5.234375 -0.9375 L 6.546875 -0.9375 L 6.546875 0 L 5.125 0 C 4.25 0 3.628906 -0.171875 3.265625 -0.515625 C 2.910156 -0.867188 2.734375 -1.476562 2.734375 -2.34375 L 2.734375 -6.203125 L 0.828125 -6.203125 L 0.828125 -7.109375 L 2.734375 -7.109375 L 2.734375 -9.125 Z M 3.890625 -9.125 "/>
</symbol>
<symbol overflow="visible" id="glyph1-9">
<path style="stroke:none;" d="M 3.90625 -6.296875 C 3.3125 -6.296875 2.863281 -6.0625 2.5625 -5.59375 C 2.257812 -5.132812 2.109375 -4.453125 2.109375 -3.546875 C 2.109375 -2.648438 2.257812 -1.96875 2.5625 -1.5 C 2.863281 -1.039062 3.3125 -0.8125 3.90625 -0.8125 C 4.507812 -0.8125 4.960938 -1.039062 5.265625 -1.5 C 5.566406 -1.96875 5.71875 -2.648438 5.71875 -3.546875 C 5.71875 -4.453125 5.566406 -5.132812 5.265625 -5.59375 C 4.960938 -6.0625 4.507812 -6.296875 3.90625 -6.296875 Z M 3.90625 -7.28125 C 4.894531 -7.28125 5.648438 -6.957031 6.171875 -6.3125 C 6.691406 -5.675781 6.953125 -4.753906 6.953125 -3.546875 C 6.953125 -2.335938 6.691406 -1.410156 6.171875 -0.765625 C 5.648438 -0.128906 4.894531 0.1875 3.90625 0.1875 C 2.925781 0.1875 2.175781 -0.128906 1.65625 -0.765625 C 1.132812 -1.410156 0.875 -2.335938 0.875 -3.546875 C 0.875 -4.753906 1.132812 -5.675781 1.65625 -6.3125 C 2.175781 -6.957031 2.925781 -7.28125 3.90625 -7.28125 Z M 3.90625 -7.28125 "/>
</symbol>
<symbol overflow="visible" id="glyph1-10">
<path style="stroke:none;" d="M 5.453125 -3.609375 C 5.453125 -4.484375 5.304688 -5.148438 5.015625 -5.609375 C 4.734375 -6.066406 4.316406 -6.296875 3.765625 -6.296875 C 3.191406 -6.296875 2.753906 -6.066406 2.453125 -5.609375 C 2.160156 -5.148438 2.015625 -4.484375 2.015625 -3.609375 C 2.015625 -2.734375 2.164062 -2.066406 2.46875 -1.609375 C 2.769531 -1.148438 3.207031 -0.921875 3.78125 -0.921875 C 4.320312 -0.921875 4.734375 -1.148438 5.015625 -1.609375 C 5.304688 -2.066406 5.453125 -2.734375 5.453125 -3.609375 Z M 6.609375 -0.453125 C 6.609375 0.609375 6.359375 1.414062 5.859375 1.96875 C 5.359375 2.519531 4.617188 2.796875 3.640625 2.796875 C 3.316406 2.796875 2.976562 2.765625 2.625 2.703125 C 2.269531 2.640625 1.921875 2.550781 1.578125 2.4375 L 1.578125 1.28125 C 1.992188 1.476562 2.367188 1.625 2.703125 1.71875 C 3.046875 1.8125 3.359375 1.859375 3.640625 1.859375 C 4.265625 1.859375 4.722656 1.6875 5.015625 1.34375 C 5.304688 1 5.453125 0.457031 5.453125 -0.28125 L 5.453125 -1.125 C 5.265625 -0.726562 5.007812 -0.429688 4.6875 -0.234375 C 4.363281 -0.046875 3.972656 0.046875 3.515625 0.046875 C 2.679688 0.046875 2.015625 -0.28125 1.515625 -0.9375 C 1.023438 -1.601562 0.78125 -2.492188 0.78125 -3.609375 C 0.78125 -4.722656 1.023438 -5.613281 1.515625 -6.28125 C 2.015625 -6.945312 2.679688 -7.28125 3.515625 -7.28125 C 3.972656 -7.28125 4.359375 -7.1875 4.671875 -7 C 4.984375 -6.820312 5.242188 -6.539062 5.453125 -6.15625 L 5.453125 -7.078125 L 6.609375 -7.078125 Z M 6.609375 -0.453125 "/>
</symbol>
<symbol overflow="visible" id="glyph1-11">
<path style="stroke:none;" d="M 6.734375 -0.359375 C 6.421875 -0.179688 6.097656 -0.046875 5.765625 0.046875 C 5.429688 0.140625 5.09375 0.1875 4.75 0.1875 C 3.644531 0.1875 2.78125 -0.140625 2.15625 -0.796875 C 1.539062 -1.460938 1.234375 -2.378906 1.234375 -3.546875 C 1.234375 -4.710938 1.539062 -5.625 2.15625 -6.28125 C 2.78125 -6.945312 3.644531 -7.28125 4.75 -7.28125 C 5.09375 -7.28125 5.425781 -7.234375 5.75 -7.140625 C 6.070312 -7.054688 6.398438 -6.921875 6.734375 -6.734375 L 6.734375 -5.515625 C 6.421875 -5.785156 6.109375 -5.984375 5.796875 -6.109375 C 5.492188 -6.234375 5.144531 -6.296875 4.75 -6.296875 C 4.019531 -6.296875 3.457031 -6.054688 3.0625 -5.578125 C 2.664062 -5.109375 2.46875 -4.429688 2.46875 -3.546875 C 2.46875 -2.671875 2.664062 -1.992188 3.0625 -1.515625 C 3.457031 -1.046875 4.019531 -0.8125 4.75 -0.8125 C 5.15625 -0.8125 5.519531 -0.875 5.84375 -1 C 6.164062 -1.125 6.460938 -1.316406 6.734375 -1.578125 Z M 6.734375 -0.359375 "/>
</symbol>
<symbol overflow="visible" id="glyph1-12">
<path style="stroke:none;" d="M 6.671875 -4.40625 L 6.671875 0 L 5.5 0 L 5.5 -4.40625 C 5.5 -5.039062 5.382812 -5.507812 5.15625 -5.8125 C 4.9375 -6.113281 4.585938 -6.265625 4.109375 -6.265625 C 3.554688 -6.265625 3.132812 -6.070312 2.84375 -5.6875 C 2.550781 -5.300781 2.40625 -4.742188 2.40625 -4.015625 L 2.40625 0 L 1.234375 0 L 1.234375 -7.109375 L 2.40625 -7.109375 L 2.40625 -6.046875 C 2.613281 -6.453125 2.894531 -6.757812 3.25 -6.96875 C 3.601562 -7.175781 4.023438 -7.28125 4.515625 -7.28125 C 5.234375 -7.28125 5.769531 -7.039062 6.125 -6.5625 C 6.488281 -6.09375 6.671875 -5.375 6.671875 -4.40625 Z M 6.671875 -4.40625 "/>
</symbol>
<symbol overflow="visible" id="glyph1-13">
<path style="stroke:none;" d="M 6.75 -9.875 L 6.75 -8.90625 L 5.421875 -8.90625 C 5.003906 -8.90625 4.710938 -8.816406 4.546875 -8.640625 C 4.378906 -8.472656 4.296875 -8.171875 4.296875 -7.734375 L 4.296875 -7.109375 L 6.75 -7.109375 L 6.75 -6.203125 L 4.296875 -6.203125 L 4.296875 0 L 3.140625 0 L 3.140625 -6.203125 L 1.234375 -6.203125 L 1.234375 -7.109375 L 3.140625 -7.109375 L 3.140625 -7.609375 C 3.140625 -8.378906 3.316406 -8.945312 3.671875 -9.3125 C 4.023438 -9.6875 4.582031 -9.875 5.34375 -9.875 Z M 6.75 -9.875 "/>
</symbol>
<symbol overflow="visible" id="glyph1-14">
<path style="stroke:none;" d="M 1.234375 -2.6875 L 1.234375 -7.09375 L 2.40625 -7.09375 L 2.40625 -2.6875 C 2.40625 -2.050781 2.515625 -1.582031 2.734375 -1.28125 C 2.960938 -0.976562 3.316406 -0.828125 3.796875 -0.828125 C 4.347656 -0.828125 4.769531 -1.019531 5.0625 -1.40625 C 5.351562 -1.800781 5.5 -2.359375 5.5 -3.078125 L 5.5 -7.09375 L 6.671875 -7.09375 L 6.671875 0 L 5.5 0 L 5.5 -1.0625 C 5.289062 -0.65625 5.003906 -0.34375 4.640625 -0.125 C 4.285156 0.0820312 3.867188 0.1875 3.390625 0.1875 C 2.660156 0.1875 2.117188 -0.0507812 1.765625 -0.53125 C 1.410156 -1.007812 1.234375 -1.726562 1.234375 -2.6875 Z M 1.234375 -2.6875 "/>
</symbol>
<symbol overflow="visible" id="glyph1-15">
<path style="stroke:none;" d="M 7.328125 -5.640625 C 7.078125 -5.835938 6.820312 -5.976562 6.5625 -6.0625 C 6.3125 -6.15625 6.03125 -6.203125 5.71875 -6.203125 C 4.988281 -6.203125 4.429688 -5.972656 4.046875 -5.515625 C 3.660156 -5.054688 3.46875 -4.394531 3.46875 -3.53125 L 3.46875 0 L 2.296875 0 L 2.296875 -7.109375 L 3.46875 -7.109375 L 3.46875 -5.71875 C 3.664062 -6.21875 3.96875 -6.601562 4.375 -6.875 C 4.78125 -7.144531 5.257812 -7.28125 5.8125 -7.28125 C 6.09375 -7.28125 6.359375 -7.242188 6.609375 -7.171875 C 6.859375 -7.097656 7.097656 -6.988281 7.328125 -6.84375 Z M 7.328125 -5.640625 "/>
</symbol>
<symbol overflow="visible" id="glyph1-16">
<path style="stroke:none;" d="M 4.453125 -3.578125 L 4.0625 -3.578125 C 3.382812 -3.578125 2.875 -3.457031 2.53125 -3.21875 C 2.1875 -2.976562 2.015625 -2.617188 2.015625 -2.140625 C 2.015625 -1.710938 2.140625 -1.378906 2.390625 -1.140625 C 2.648438 -0.910156 3.007812 -0.796875 3.46875 -0.796875 C 4.113281 -0.796875 4.617188 -1.019531 4.984375 -1.46875 C 5.359375 -1.914062 5.546875 -2.53125 5.546875 -3.3125 L 5.546875 -3.578125 Z M 6.71875 -4.0625 L 6.71875 0 L 5.546875 0 L 5.546875 -1.046875 C 5.296875 -0.628906 4.976562 -0.316406 4.59375 -0.109375 C 4.21875 0.0859375 3.757812 0.1875 3.21875 0.1875 C 2.5 0.1875 1.921875 -0.015625 1.484375 -0.421875 C 1.054688 -0.835938 0.84375 -1.382812 0.84375 -2.0625 C 0.84375 -2.851562 1.109375 -3.453125 1.640625 -3.859375 C 2.171875 -4.273438 2.953125 -4.484375 3.984375 -4.484375 L 5.546875 -4.484375 L 5.546875 -4.671875 C 5.546875 -5.234375 5.398438 -5.644531 5.109375 -5.90625 C 4.828125 -6.164062 4.378906 -6.296875 3.765625 -6.296875 C 3.359375 -6.296875 2.953125 -6.238281 2.546875 -6.125 C 2.140625 -6.007812 1.742188 -5.84375 1.359375 -5.625 L 1.359375 -6.78125 C 1.796875 -6.945312 2.210938 -7.070312 2.609375 -7.15625 C 3.003906 -7.238281 3.390625 -7.28125 3.765625 -7.28125 C 4.347656 -7.28125 4.847656 -7.191406 5.265625 -7.015625 C 5.679688 -6.847656 6.019531 -6.585938 6.28125 -6.234375 C 6.4375 -6.023438 6.546875 -5.765625 6.609375 -5.453125 C 6.679688 -5.140625 6.71875 -4.675781 6.71875 -4.0625 Z M 6.71875 -4.0625 "/>
</symbol>
<symbol overflow="visible" id="glyph1-17">
<path style="stroke:none;" d="M 4.296875 -6.390625 C 4.429688 -6.691406 4.609375 -6.914062 4.828125 -7.0625 C 5.054688 -7.207031 5.328125 -7.28125 5.640625 -7.28125 C 6.210938 -7.28125 6.613281 -7.054688 6.84375 -6.609375 C 7.082031 -6.171875 7.203125 -5.34375 7.203125 -4.125 L 7.203125 0 L 6.140625 0 L 6.140625 -4.0625 C 6.140625 -5.070312 6.082031 -5.695312 5.96875 -5.9375 C 5.851562 -6.175781 5.648438 -6.296875 5.359375 -6.296875 C 5.015625 -6.296875 4.78125 -6.164062 4.65625 -5.90625 C 4.53125 -5.644531 4.46875 -5.03125 4.46875 -4.0625 L 4.46875 0 L 3.40625 0 L 3.40625 -4.0625 C 3.40625 -5.082031 3.34375 -5.707031 3.21875 -5.9375 C 3.101562 -6.175781 2.890625 -6.296875 2.578125 -6.296875 C 2.265625 -6.296875 2.046875 -6.164062 1.921875 -5.90625 C 1.804688 -5.644531 1.75 -5.03125 1.75 -4.0625 L 1.75 0 L 0.6875 0 L 0.6875 -7.109375 L 1.75 -7.109375 L 1.75 -6.5 C 1.894531 -6.75 2.070312 -6.941406 2.28125 -7.078125 C 2.488281 -7.210938 2.722656 -7.28125 2.984375 -7.28125 C 3.304688 -7.28125 3.570312 -7.207031 3.78125 -7.0625 C 4 -6.914062 4.171875 -6.691406 4.296875 -6.390625 Z M 4.296875 -6.390625 "/>
</symbol>
<symbol overflow="visible" id="glyph1-18">
<path style="stroke:none;" d="M 6.671875 -4.40625 L 6.671875 0 L 5.5 0 L 5.5 -4.40625 C 5.5 -5.039062 5.382812 -5.507812 5.15625 -5.8125 C 4.9375 -6.113281 4.585938 -6.265625 4.109375 -6.265625 C 3.554688 -6.265625 3.132812 -6.070312 2.84375 -5.6875 C 2.550781 -5.300781 2.40625 -4.742188 2.40625 -4.015625 L 2.40625 0 L 1.234375 0 L 1.234375 -9.875 L 2.40625 -9.875 L 2.40625 -6.046875 C 2.613281 -6.453125 2.894531 -6.757812 3.25 -6.96875 C 3.601562 -7.175781 4.023438 -7.28125 4.515625 -7.28125 C 5.234375 -7.28125 5.769531 -7.039062 6.125 -6.5625 C 6.488281 -6.09375 6.671875 -5.375 6.671875 -4.40625 Z M 6.671875 -4.40625 "/>
</symbol>
<symbol overflow="visible" id="glyph1-19">
<path style="stroke:none;" d="M 0.640625 -7.109375 L 1.84375 -7.109375 L 3.90625 -1.140625 L 5.984375 -7.109375 L 7.1875 -7.109375 L 4.671875 0 L 3.15625 0 Z M 0.640625 -7.109375 "/>
</symbol>
<symbol overflow="visible" id="glyph1-20">
<path style="stroke:none;" d="M 7.015625 -0.78125 C 6.671875 -0.46875 6.28125 -0.226562 5.84375 -0.0625 C 5.414062 0.101562 4.953125 0.1875 4.453125 0.1875 C 3.253906 0.1875 2.316406 -0.242188 1.640625 -1.109375 C 0.972656 -1.972656 0.640625 -3.179688 0.640625 -4.734375 C 0.640625 -6.273438 0.976562 -7.476562 1.65625 -8.34375 C 2.332031 -9.21875 3.273438 -9.65625 4.484375 -9.65625 C 4.878906 -9.65625 5.257812 -9.597656 5.625 -9.484375 C 5.988281 -9.367188 6.34375 -9.195312 6.6875 -8.96875 L 6.6875 -7.65625 C 6.34375 -7.976562 5.988281 -8.21875 5.625 -8.375 C 5.269531 -8.53125 4.890625 -8.609375 4.484375 -8.609375 C 3.648438 -8.609375 3.023438 -8.285156 2.609375 -7.640625 C 2.191406 -6.992188 1.984375 -6.023438 1.984375 -4.734375 C 1.984375 -3.410156 2.1875 -2.429688 2.59375 -1.796875 C 3 -1.171875 3.617188 -0.859375 4.453125 -0.859375 C 4.734375 -0.859375 4.976562 -0.890625 5.1875 -0.953125 C 5.40625 -1.015625 5.601562 -1.117188 5.78125 -1.265625 L 5.78125 -3.8125 L 4.40625 -3.8125 L 4.40625 -4.859375 L 7.015625 -4.859375 Z M 7.015625 -0.78125 "/>
</symbol>
<symbol overflow="visible" id="glyph1-21">
<path style="stroke:none;" d="M 5.453125 -6.203125 L 5.453125 -9.875 L 6.609375 -9.875 L 6.609375 0 L 5.453125 0 L 5.453125 -0.890625 C 5.253906 -0.546875 4.992188 -0.28125 4.671875 -0.09375 C 4.347656 0.09375 3.972656 0.1875 3.546875 0.1875 C 2.691406 0.1875 2.015625 -0.144531 1.515625 -0.8125 C 1.023438 -1.476562 0.78125 -2.398438 0.78125 -3.578125 C 0.78125 -4.734375 1.023438 -5.640625 1.515625 -6.296875 C 2.015625 -6.953125 2.691406 -7.28125 3.546875 -7.28125 C 3.972656 -7.28125 4.347656 -7.1875 4.671875 -7 C 5.003906 -6.820312 5.265625 -6.554688 5.453125 -6.203125 Z M 2.015625 -3.546875 C 2.015625 -2.640625 2.15625 -1.957031 2.4375 -1.5 C 2.726562 -1.039062 3.15625 -0.8125 3.71875 -0.8125 C 4.28125 -0.8125 4.707031 -1.039062 5 -1.5 C 5.300781 -1.96875 5.453125 -2.648438 5.453125 -3.546875 C 5.453125 -4.453125 5.300781 -5.132812 5 -5.59375 C 4.707031 -6.0625 4.28125 -6.296875 3.71875 -6.296875 C 3.15625 -6.296875 2.726562 -6.0625 2.4375 -5.59375 C 2.15625 -5.132812 2.015625 -4.453125 2.015625 -3.546875 Z M 2.015625 -3.546875 "/>
</symbol>
<symbol overflow="visible" id="glyph1-22">
<path style="stroke:none;" d="M 0.875 -9.484375 L 2.5 -9.484375 L 5.703125 -1.671875 L 5.703125 -9.484375 L 6.9375 -9.484375 L 6.9375 0 L 5.3125 0 L 2.125 -7.796875 L 2.125 0 L 0.875 0 Z M 0.875 -9.484375 "/>
</symbol>
<symbol overflow="visible" id="glyph1-23">
<path style="stroke:none;" d="M 7.09375 -7.109375 L 4.546875 -3.703125 L 7.34375 0 L 6 0 L 3.90625 -2.84375 L 1.828125 0 L 0.484375 0 L 3.28125 -3.703125 L 0.734375 -7.109375 L 2.03125 -7.109375 L 3.90625 -4.53125 L 5.78125 -7.109375 Z M 7.09375 -7.109375 "/>
</symbol>
<symbol overflow="visible" id="glyph1-24">
<path style="stroke:none;" d="M 0.296875 -9.484375 L 7.53125 -9.484375 L 7.53125 -8.390625 L 4.5625 -8.390625 L 4.5625 0 L 3.28125 0 L 3.28125 -8.390625 L 0.296875 -8.390625 Z M 0.296875 -9.484375 "/>
</symbol>
<symbol overflow="visible" id="glyph1-25">
<path style="stroke:none;" d="M 2.765625 -1.046875 C 3.847656 -1.046875 4.601562 -1.3125 5.03125 -1.84375 C 5.457031 -2.375 5.671875 -3.335938 5.671875 -4.734375 C 5.671875 -6.128906 5.457031 -7.09375 5.03125 -7.625 C 4.601562 -8.15625 3.847656 -8.421875 2.765625 -8.421875 L 2.15625 -8.421875 L 2.15625 -1.046875 Z M 2.796875 -9.484375 C 4.242188 -9.484375 5.304688 -9.097656 5.984375 -8.328125 C 6.671875 -7.554688 7.015625 -6.359375 7.015625 -4.734375 C 7.015625 -3.109375 6.671875 -1.910156 5.984375 -1.140625 C 5.304688 -0.378906 4.242188 0 2.796875 0 L 0.875 0 L 0.875 -9.484375 Z M 2.796875 -9.484375 "/>
</symbol>
<symbol overflow="visible" id="glyph1-26">
<path style="stroke:none;" d="M 6.8125 -0.34375 C 6.488281 -0.164062 6.15625 -0.0351562 5.8125 0.046875 C 5.46875 0.140625 5.101562 0.1875 4.71875 0.1875 C 3.5 0.1875 2.550781 -0.238281 1.875 -1.09375 C 1.207031 -1.957031 0.875 -3.171875 0.875 -4.734375 C 0.875 -6.273438 1.210938 -7.476562 1.890625 -8.34375 C 2.566406 -9.21875 3.507812 -9.65625 4.71875 -9.65625 C 5.101562 -9.65625 5.46875 -9.609375 5.8125 -9.515625 C 6.15625 -9.429688 6.488281 -9.300781 6.8125 -9.125 L 6.8125 -7.8125 C 6.5 -8.070312 6.160156 -8.269531 5.796875 -8.40625 C 5.441406 -8.539062 5.082031 -8.609375 4.71875 -8.609375 C 3.882812 -8.609375 3.257812 -8.285156 2.84375 -7.640625 C 2.425781 -6.992188 2.21875 -6.023438 2.21875 -4.734375 C 2.21875 -3.429688 2.425781 -2.457031 2.84375 -1.8125 C 3.257812 -1.175781 3.882812 -0.859375 4.71875 -0.859375 C 5.09375 -0.859375 5.457031 -0.925781 5.8125 -1.0625 C 6.164062 -1.195312 6.5 -1.394531 6.8125 -1.65625 Z M 6.8125 -0.34375 "/>
</symbol>
<symbol overflow="visible" id="glyph1-27">
<path style="stroke:none;" d="M 0.546875 -9.484375 L 2.265625 -9.484375 L 3.890625 -4.65625 L 5.546875 -9.484375 L 7.265625 -9.484375 L 7.265625 0 L 6.078125 0 L 6.078125 -8.375 L 4.390625 -3.375 L 3.421875 -3.375 L 1.734375 -8.375 L 1.734375 0 L 0.546875 0 Z M 0.546875 -9.484375 "/>
</symbol>
<symbol overflow="visible" id="glyph1-28">
<path style="stroke:none;" d="M 1.359375 -9.484375 L 2.65625 -9.484375 L 2.65625 -1.078125 L 7.234375 -1.078125 L 7.234375 0 L 1.359375 0 Z M 1.359375 -9.484375 "/>
</symbol>
<symbol overflow="visible" id="glyph2-0">
<path style="stroke:none;" d="M 0.640625 2.296875 L 0.640625 -9.171875 L 7.140625 -9.171875 L 7.140625 2.296875 Z M 1.375 1.578125 L 6.421875 1.578125 L 6.421875 -8.4375 L 1.375 -8.4375 Z M 1.375 1.578125 "/>
</symbol>
<symbol overflow="visible" id="glyph2-1">
<path style="stroke:none;" d="M 6.9375 -1.734375 L 3.125 -1.734375 L 2.515625 0 L 0.0625 0 L 3.578125 -9.484375 L 6.484375 -9.484375 L 10 0 L 7.546875 0 Z M 3.734375 -3.484375 L 6.328125 -3.484375 L 5.03125 -7.25 Z M 3.734375 -3.484375 "/>
</symbol>
<symbol overflow="visible" id="glyph2-2">
<path style="stroke:none;" d="M 5.921875 -6.0625 L 5.921875 -9.875 L 8.21875 -9.875 L 8.21875 0 L 5.921875 0 L 5.921875 -1.03125 C 5.609375 -0.613281 5.265625 -0.304688 4.890625 -0.109375 C 4.515625 0.0859375 4.082031 0.1875 3.59375 0.1875 C 2.707031 0.1875 1.984375 -0.160156 1.421875 -0.859375 C 0.859375 -1.554688 0.578125 -2.453125 0.578125 -3.546875 C 0.578125 -4.640625 0.859375 -5.535156 1.421875 -6.234375 C 1.984375 -6.929688 2.707031 -7.28125 3.59375 -7.28125 C 4.082031 -7.28125 4.515625 -7.179688 4.890625 -6.984375 C 5.265625 -6.785156 5.609375 -6.476562 5.921875 -6.0625 Z M 4.4375 -1.46875 C 4.914062 -1.46875 5.28125 -1.644531 5.53125 -2 C 5.789062 -2.351562 5.921875 -2.867188 5.921875 -3.546875 C 5.921875 -4.222656 5.789062 -4.738281 5.53125 -5.09375 C 5.28125 -5.445312 4.914062 -5.625 4.4375 -5.625 C 3.945312 -5.625 3.570312 -5.445312 3.3125 -5.09375 C 3.0625 -4.738281 2.9375 -4.222656 2.9375 -3.546875 C 2.9375 -2.867188 3.0625 -2.351562 3.3125 -2 C 3.570312 -1.644531 3.945312 -1.46875 4.4375 -1.46875 Z M 4.4375 -1.46875 "/>
</symbol>
<symbol overflow="visible" id="glyph2-3">
<path style="stroke:none;" d="M 7.6875 -5.921875 C 7.96875 -6.367188 8.304688 -6.707031 8.703125 -6.9375 C 9.097656 -7.164062 9.535156 -7.28125 10.015625 -7.28125 C 10.828125 -7.28125 11.445312 -7.023438 11.875 -6.515625 C 12.300781 -6.015625 12.515625 -5.285156 12.515625 -4.328125 L 12.515625 0 L 10.234375 0 L 10.234375 -3.703125 C 10.234375 -3.765625 10.234375 -3.820312 10.234375 -3.875 C 10.242188 -3.9375 10.25 -4.019531 10.25 -4.125 C 10.25 -4.632812 10.171875 -5 10.015625 -5.21875 C 9.867188 -5.445312 9.632812 -5.5625 9.3125 -5.5625 C 8.875 -5.5625 8.535156 -5.382812 8.296875 -5.03125 C 8.066406 -4.675781 7.945312 -4.160156 7.9375 -3.484375 L 7.9375 0 L 5.65625 0 L 5.65625 -3.703125 C 5.65625 -4.492188 5.585938 -5 5.453125 -5.21875 C 5.316406 -5.445312 5.078125 -5.5625 4.734375 -5.5625 C 4.296875 -5.5625 3.957031 -5.382812 3.71875 -5.03125 C 3.476562 -4.675781 3.359375 -4.164062 3.359375 -3.5 L 3.359375 0 L 1.078125 0 L 1.078125 -7.109375 L 3.359375 -7.109375 L 3.359375 -6.0625 C 3.640625 -6.46875 3.960938 -6.769531 4.328125 -6.96875 C 4.691406 -7.175781 5.085938 -7.28125 5.515625 -7.28125 C 6.015625 -7.28125 6.453125 -7.160156 6.828125 -6.921875 C 7.203125 -6.679688 7.488281 -6.347656 7.6875 -5.921875 Z M 7.6875 -5.921875 "/>
</symbol>
<symbol overflow="visible" id="glyph2-4">
<path style="stroke:none;" d="M 1.09375 -7.109375 L 3.359375 -7.109375 L 3.359375 0 L 1.09375 0 Z M 1.09375 -9.875 L 3.359375 -9.875 L 3.359375 -8.03125 L 1.09375 -8.03125 Z M 1.09375 -9.875 "/>
</symbol>
<symbol overflow="visible" id="glyph2-5">
<path style="stroke:none;" d="M 8.234375 -4.328125 L 8.234375 0 L 5.953125 0 L 5.953125 -3.3125 C 5.953125 -3.925781 5.9375 -4.347656 5.90625 -4.578125 C 5.882812 -4.816406 5.835938 -4.988281 5.765625 -5.09375 C 5.679688 -5.238281 5.5625 -5.351562 5.40625 -5.4375 C 5.257812 -5.519531 5.085938 -5.5625 4.890625 -5.5625 C 4.410156 -5.5625 4.035156 -5.378906 3.765625 -5.015625 C 3.492188 -4.648438 3.359375 -4.144531 3.359375 -3.5 L 3.359375 0 L 1.09375 0 L 1.09375 -7.109375 L 3.359375 -7.109375 L 3.359375 -6.0625 C 3.703125 -6.476562 4.066406 -6.785156 4.453125 -6.984375 C 4.835938 -7.179688 5.265625 -7.28125 5.734375 -7.28125 C 6.554688 -7.28125 7.175781 -7.023438 7.59375 -6.515625 C 8.019531 -6.015625 8.234375 -5.285156 8.234375 -4.328125 Z M 8.234375 -4.328125 "/>
</symbol>
<symbol overflow="visible" id="glyph2-6">
<path style="stroke:none;" d="M 6.640625 -6.890625 L 6.640625 -5.15625 C 6.160156 -5.363281 5.691406 -5.515625 5.234375 -5.609375 C 4.785156 -5.710938 4.359375 -5.765625 3.953125 -5.765625 C 3.523438 -5.765625 3.203125 -5.710938 2.984375 -5.609375 C 2.773438 -5.503906 2.671875 -5.335938 2.671875 -5.109375 C 2.671875 -4.929688 2.75 -4.789062 2.90625 -4.6875 C 3.070312 -4.59375 3.359375 -4.519531 3.765625 -4.46875 L 4.171875 -4.421875 C 5.335938 -4.273438 6.117188 -4.03125 6.515625 -3.6875 C 6.921875 -3.351562 7.125 -2.820312 7.125 -2.09375 C 7.125 -1.332031 6.84375 -0.757812 6.28125 -0.375 C 5.726562 0 4.894531 0.1875 3.78125 0.1875 C 3.3125 0.1875 2.828125 0.148438 2.328125 0.078125 C 1.828125 0.00390625 1.3125 -0.109375 0.78125 -0.265625 L 0.78125 -1.984375 C 1.226562 -1.765625 1.691406 -1.597656 2.171875 -1.484375 C 2.648438 -1.378906 3.132812 -1.328125 3.625 -1.328125 C 4.070312 -1.328125 4.40625 -1.382812 4.625 -1.5 C 4.851562 -1.625 4.96875 -1.8125 4.96875 -2.0625 C 4.96875 -2.257812 4.890625 -2.40625 4.734375 -2.5 C 4.578125 -2.601562 4.269531 -2.6875 3.8125 -2.75 L 3.40625 -2.796875 C 2.394531 -2.921875 1.6875 -3.15625 1.28125 -3.5 C 0.875 -3.84375 0.671875 -4.363281 0.671875 -5.0625 C 0.671875 -5.8125 0.925781 -6.367188 1.4375 -6.734375 C 1.957031 -7.097656 2.753906 -7.28125 3.828125 -7.28125 C 4.242188 -7.28125 4.679688 -7.25 5.140625 -7.1875 C 5.597656 -7.125 6.097656 -7.023438 6.640625 -6.890625 Z M 6.640625 -6.890625 "/>
</symbol>
<symbol overflow="visible" id="glyph2-7">
<path style="stroke:none;" d="M 3.578125 -9.125 L 3.578125 -7.109375 L 5.921875 -7.109375 L 5.921875 -5.484375 L 3.578125 -5.484375 L 3.578125 -2.46875 C 3.578125 -2.132812 3.640625 -1.910156 3.765625 -1.796875 C 3.898438 -1.679688 4.160156 -1.625 4.546875 -1.625 L 5.71875 -1.625 L 5.71875 0 L 3.765625 0 C 2.867188 0 2.234375 -0.1875 1.859375 -0.5625 C 1.484375 -0.9375 1.296875 -1.570312 1.296875 -2.46875 L 1.296875 -5.484375 L 0.171875 -5.484375 L 0.171875 -7.109375 L 1.296875 -7.109375 L 1.296875 -9.125 Z M 3.578125 -9.125 "/>
</symbol>
<symbol overflow="visible" id="glyph2-8">
<path style="stroke:none;" d="M 6.375 -5.171875 C 6.175781 -5.265625 5.976562 -5.332031 5.78125 -5.375 C 5.582031 -5.425781 5.382812 -5.453125 5.1875 -5.453125 C 4.601562 -5.453125 4.148438 -5.265625 3.828125 -4.890625 C 3.515625 -4.515625 3.359375 -3.976562 3.359375 -3.28125 L 3.359375 0 L 1.09375 0 L 1.09375 -7.109375 L 3.359375 -7.109375 L 3.359375 -5.9375 C 3.648438 -6.40625 3.984375 -6.742188 4.359375 -6.953125 C 4.742188 -7.171875 5.203125 -7.28125 5.734375 -7.28125 C 5.804688 -7.28125 5.882812 -7.273438 5.96875 -7.265625 C 6.0625 -7.265625 6.191406 -7.253906 6.359375 -7.234375 Z M 6.375 -5.171875 "/>
</symbol>
<symbol overflow="visible" id="glyph2-9">
<path style="stroke:none;" d="M 4.28125 -3.203125 C 3.800781 -3.203125 3.441406 -3.117188 3.203125 -2.953125 C 2.960938 -2.796875 2.84375 -2.5625 2.84375 -2.25 C 2.84375 -1.957031 2.9375 -1.726562 3.125 -1.5625 C 3.320312 -1.40625 3.59375 -1.328125 3.9375 -1.328125 C 4.363281 -1.328125 4.722656 -1.476562 5.015625 -1.78125 C 5.304688 -2.09375 5.453125 -2.476562 5.453125 -2.9375 L 5.453125 -3.203125 Z M 7.75 -4.0625 L 7.75 0 L 5.453125 0 L 5.453125 -1.046875 C 5.148438 -0.617188 4.804688 -0.304688 4.421875 -0.109375 C 4.046875 0.0859375 3.585938 0.1875 3.046875 0.1875 C 2.304688 0.1875 1.707031 -0.0234375 1.25 -0.453125 C 0.789062 -0.890625 0.5625 -1.453125 0.5625 -2.140625 C 0.5625 -2.972656 0.847656 -3.582031 1.421875 -3.96875 C 1.992188 -4.351562 2.894531 -4.546875 4.125 -4.546875 L 5.453125 -4.546875 L 5.453125 -4.734375 C 5.453125 -5.085938 5.3125 -5.347656 5.03125 -5.515625 C 4.75 -5.679688 4.304688 -5.765625 3.703125 -5.765625 C 3.222656 -5.765625 2.769531 -5.71875 2.34375 -5.625 C 1.925781 -5.53125 1.539062 -5.382812 1.1875 -5.1875 L 1.1875 -6.921875 C 1.664062 -7.035156 2.148438 -7.125 2.640625 -7.1875 C 3.140625 -7.25 3.632812 -7.28125 4.125 -7.28125 C 5.40625 -7.28125 6.328125 -7.023438 6.890625 -6.515625 C 7.460938 -6.015625 7.75 -5.195312 7.75 -4.0625 Z M 7.75 -4.0625 "/>
</symbol>
<symbol overflow="visible" id="glyph2-10">
<path style="stroke:none;" d="M 4.46875 -5.65625 C 3.96875 -5.65625 3.582031 -5.472656 3.3125 -5.109375 C 3.050781 -4.753906 2.921875 -4.234375 2.921875 -3.546875 C 2.921875 -2.867188 3.050781 -2.347656 3.3125 -1.984375 C 3.582031 -1.617188 3.96875 -1.4375 4.46875 -1.4375 C 4.96875 -1.4375 5.347656 -1.617188 5.609375 -1.984375 C 5.867188 -2.347656 6 -2.867188 6 -3.546875 C 6 -4.234375 5.867188 -4.753906 5.609375 -5.109375 C 5.347656 -5.472656 4.96875 -5.65625 4.46875 -5.65625 Z M 4.46875 -7.28125 C 5.695312 -7.28125 6.65625 -6.945312 7.34375 -6.28125 C 8.03125 -5.625 8.375 -4.710938 8.375 -3.546875 C 8.375 -2.378906 8.03125 -1.460938 7.34375 -0.796875 C 6.65625 -0.140625 5.695312 0.1875 4.46875 0.1875 C 3.25 0.1875 2.289062 -0.140625 1.59375 -0.796875 C 0.90625 -1.460938 0.5625 -2.378906 0.5625 -3.546875 C 0.5625 -4.710938 0.90625 -5.625 1.59375 -6.28125 C 2.289062 -6.945312 3.25 -7.28125 4.46875 -7.28125 Z M 4.46875 -7.28125 "/>
</symbol>
<symbol overflow="visible" id="glyph2-11">
<path style="stroke:none;" d="M 8.703125 -0.515625 C 8.253906 -0.285156 7.785156 -0.113281 7.296875 0 C 6.816406 0.125 6.3125 0.1875 5.78125 0.1875 C 4.207031 0.1875 2.957031 -0.253906 2.03125 -1.140625 C 1.101562 -2.023438 0.640625 -3.222656 0.640625 -4.734375 C 0.640625 -6.242188 1.101562 -7.441406 2.03125 -8.328125 C 2.957031 -9.210938 4.207031 -9.65625 5.78125 -9.65625 C 6.3125 -9.65625 6.816406 -9.59375 7.296875 -9.46875 C 7.785156 -9.351562 8.253906 -9.175781 8.703125 -8.9375 L 8.703125 -6.984375 C 8.253906 -7.296875 7.804688 -7.519531 7.359375 -7.65625 C 6.921875 -7.800781 6.460938 -7.875 5.984375 -7.875 C 5.109375 -7.875 4.421875 -7.59375 3.921875 -7.03125 C 3.421875 -6.476562 3.171875 -5.710938 3.171875 -4.734375 C 3.171875 -3.753906 3.421875 -2.984375 3.921875 -2.421875 C 4.421875 -1.867188 5.109375 -1.59375 5.984375 -1.59375 C 6.460938 -1.59375 6.921875 -1.660156 7.359375 -1.796875 C 7.804688 -1.941406 8.253906 -2.171875 8.703125 -2.484375 Z M 8.703125 -0.515625 "/>
</symbol>
<symbol overflow="visible" id="glyph2-12">
<path style="stroke:none;" d="M 1.015625 -2.765625 L 1.015625 -7.109375 L 3.296875 -7.109375 L 3.296875 -6.40625 C 3.296875 -6.019531 3.289062 -5.535156 3.28125 -4.953125 C 3.28125 -4.367188 3.28125 -3.976562 3.28125 -3.78125 C 3.28125 -3.207031 3.296875 -2.796875 3.328125 -2.546875 C 3.359375 -2.296875 3.410156 -2.113281 3.484375 -2 C 3.578125 -1.851562 3.695312 -1.738281 3.84375 -1.65625 C 4 -1.570312 4.175781 -1.53125 4.375 -1.53125 C 4.84375 -1.53125 5.210938 -1.710938 5.484375 -2.078125 C 5.753906 -2.441406 5.890625 -2.945312 5.890625 -3.59375 L 5.890625 -7.109375 L 8.15625 -7.109375 L 8.15625 0 L 5.890625 0 L 5.890625 -1.03125 C 5.546875 -0.613281 5.179688 -0.304688 4.796875 -0.109375 C 4.421875 0.0859375 4 0.1875 3.53125 0.1875 C 2.707031 0.1875 2.082031 -0.0625 1.65625 -0.5625 C 1.226562 -1.070312 1.015625 -1.804688 1.015625 -2.765625 Z M 1.015625 -2.765625 "/>
</symbol>
<symbol overflow="visible" id="glyph2-13">
<path style="stroke:none;" d="M 8.1875 -3.578125 L 8.1875 -2.921875 L 2.875 -2.921875 C 2.925781 -2.390625 3.117188 -1.988281 3.453125 -1.71875 C 3.785156 -1.457031 4.25 -1.328125 4.84375 -1.328125 C 5.3125 -1.328125 5.796875 -1.394531 6.296875 -1.53125 C 6.804688 -1.675781 7.328125 -1.894531 7.859375 -2.1875 L 7.859375 -0.4375 C 7.316406 -0.226562 6.773438 -0.0703125 6.234375 0.03125 C 5.703125 0.132812 5.164062 0.1875 4.625 0.1875 C 3.34375 0.1875 2.34375 -0.140625 1.625 -0.796875 C 0.914062 -1.453125 0.5625 -2.367188 0.5625 -3.546875 C 0.5625 -4.703125 0.910156 -5.613281 1.609375 -6.28125 C 2.304688 -6.945312 3.269531 -7.28125 4.5 -7.28125 C 5.613281 -7.28125 6.503906 -6.941406 7.171875 -6.265625 C 7.847656 -5.597656 8.1875 -4.703125 8.1875 -3.578125 Z M 5.859375 -4.328125 C 5.859375 -4.765625 5.726562 -5.113281 5.46875 -5.375 C 5.21875 -5.632812 4.890625 -5.765625 4.484375 -5.765625 C 4.046875 -5.765625 3.6875 -5.640625 3.40625 -5.390625 C 3.132812 -5.148438 2.96875 -4.796875 2.90625 -4.328125 Z M 5.859375 -4.328125 "/>
</symbol>
</g>
</defs>
<g id="surface25169">
<rect x="0" y="0" width="1146" height="548" style="fill:rgb(100%,100%,100%);fill-opacity:1;stroke:none;"/>
<path style="fill-rule:evenodd;fill:rgb(100%,100%,100%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 28.5 4.95 L 35.825 4.95 L 35.825 6.35 L 28.5 6.35 Z M 28.5 4.95 " transform="matrix(20,0,0,20,-26,-8)"/>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-1" x="537.601562" y="110"/>
<use xlink:href="#glyph0-2" x="549.984375" y="110"/>
<use xlink:href="#glyph0-3" x="561.371094" y="110"/>
<use xlink:href="#glyph0-4" x="572.816406" y="110"/>
<use xlink:href="#glyph0-5" x="578.304688" y="110"/>
<use xlink:href="#glyph0-6" x="585.960938" y="110"/>
<use xlink:href="#glyph0-7" x="623.109375" y="110"/>
<use xlink:href="#glyph0-8" x="623.109375" y="110"/>
<use xlink:href="#glyph0-9" x="633.96875" y="110"/>
<use xlink:href="#glyph0-10" x="650.648438" y="110"/>
<use xlink:href="#glyph0-11" x="662.09375" y="110"/>
<use xlink:href="#glyph0-12" x="667.582031" y="110"/>
<use xlink:href="#glyph0-5" x="678.382812" y="110"/>
<use xlink:href="#glyph0-8" x="686.039062" y="110"/>
</g>
<path style="fill-rule:evenodd;fill:rgb(100%,100%,100%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 10.6 7 L 19.475 7 L 19.475 8.4 L 10.6 8.4 Z M 10.6 7 " transform="matrix(20,0,0,20,-26,-8)"/>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-13" x="191" y="151"/>
<use xlink:href="#glyph0-10" x="204.59375" y="151"/>
<use xlink:href="#glyph0-8" x="216.039063" y="151"/>
<use xlink:href="#glyph0-14" x="226.898438" y="151"/>
<use xlink:href="#glyph0-15" x="238.285156" y="151"/>
<use xlink:href="#glyph0-5" x="249.808594" y="151"/>
<use xlink:href="#glyph0-12" x="257.464844" y="151"/>
<use xlink:href="#glyph0-16" x="268.265625" y="151"/>
<use xlink:href="#glyph0-17" x="277.757812" y="151"/>
<use xlink:href="#glyph0-6" x="288.402344" y="151"/>
<use xlink:href="#glyph0-18" x="293.96875" y="151"/>
<use xlink:href="#glyph0-11" x="305.707031" y="151"/>
<use xlink:href="#glyph0-2" x="311.195312" y="151"/>
<use xlink:href="#glyph0-19" x="322.582031" y="151"/>
<use xlink:href="#glyph0-5" x="332.113281" y="151"/>
<use xlink:href="#glyph0-8" x="339.769531" y="151"/>
<use xlink:href="#glyph0-20" x="350.628906" y="151"/>
</g>
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-dasharray:0.4,0.4;stroke-miterlimit:10;" d="M 28.451953 5.65 L 22.3 5.65 L 22.3 7.7 L 19.85957 7.7 " transform="matrix(20,0,0,20,-26,-8)"/>
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 20.491797 7.45 L 19.691797 7.7 L 20.491797 7.95 " transform="matrix(20,0,0,20,-26,-8)"/>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph1-1" x="422" y="121.5"/>
<use xlink:href="#glyph1-2" x="429.695313" y="121.5"/>
<use xlink:href="#glyph1-2" x="437.390625" y="121.5"/>
<use xlink:href="#glyph1-3" x="445.085938" y="121.5"/>
<use xlink:href="#glyph1-4" x="452.78125" y="121.5"/>
<use xlink:href="#glyph1-5" x="460.476563" y="121.5"/>
<use xlink:href="#glyph1-6" x="468.171875" y="121.5"/>
<use xlink:href="#glyph1-7" x="475.867188" y="121.5"/>
<use xlink:href="#glyph1-8" x="483.5625" y="121.5"/>
<use xlink:href="#glyph1-9" x="491.257812" y="121.5"/>
</g>
<path style="fill-rule:evenodd;fill:rgb(100%,100%,100%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 30.75 11.35 L 33.669922 11.35 L 33.669922 12.75 L 30.75 12.75 Z M 30.75 11.35 " transform="matrix(20,0,0,20,-26,-8)"/>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-1" x="594.019531" y="238"/>
<use xlink:href="#glyph0-2" x="606.402344" y="238"/>
<use xlink:href="#glyph0-3" x="617.789062" y="238"/>
<use xlink:href="#glyph0-4" x="629.234375" y="238"/>
<use xlink:href="#glyph0-5" x="634.722656" y="238"/>
</g>
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-dasharray:0.4,0.4;stroke-miterlimit:10;" d="M 32.209961 11.299805 L 32.209961 9.424805 L 32.215039 9.424805 L 32.215039 6.685352 " transform="matrix(20,0,0,20,-26,-8)"/>
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 32.465039 7.317578 L 32.215039 6.517578 L 31.965039 7.317578 " transform="matrix(20,0,0,20,-26,-8)"/>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph1-10" x="529.753906" y="176.496094"/>
<use xlink:href="#glyph1-5" x="537.449219" y="176.496094"/>
<use xlink:href="#glyph1-8" x="545.144531" y="176.496094"/>
<use xlink:href="#glyph1-6" x="552.839844" y="176.496094"/>
<use xlink:href="#glyph1-7" x="560.535156" y="176.496094"/>
<use xlink:href="#glyph1-11" x="568.230469" y="176.496094"/>
<use xlink:href="#glyph1-9" x="575.925781" y="176.496094"/>
<use xlink:href="#glyph1-12" x="583.621094" y="176.496094"/>
<use xlink:href="#glyph1-13" x="591.316406" y="176.496094"/>
<use xlink:href="#glyph1-4" x="599.011719" y="176.496094"/>
<use xlink:href="#glyph1-10" x="606.707031" y="176.496094"/>
<use xlink:href="#glyph1-14" x="614.402344" y="176.496094"/>
<use xlink:href="#glyph1-15" x="622.097656" y="176.496094"/>
<use xlink:href="#glyph1-16" x="629.792969" y="176.496094"/>
<use xlink:href="#glyph1-8" x="637.488281" y="176.496094"/>
<use xlink:href="#glyph1-4" x="645.183594" y="176.496094"/>
<use xlink:href="#glyph1-9" x="652.878906" y="176.496094"/>
<use xlink:href="#glyph1-12" x="660.574219" y="176.496094"/>
<use xlink:href="#glyph1-7" x="668.269531" y="176.496094"/>
<use xlink:href="#glyph1-13" x="675.964844" y="176.496094"/>
<use xlink:href="#glyph1-15" x="683.660156" y="176.496094"/>
<use xlink:href="#glyph1-9" x="691.355469" y="176.496094"/>
<use xlink:href="#glyph1-17" x="699.050781" y="176.496094"/>
</g>
<path style="fill-rule:evenodd;fill:rgb(100%,100%,100%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 45.8 0.45 L 48.322461 0.45 L 48.322461 1.85 L 45.8 1.85 Z M 45.8 0.45 " transform="matrix(20,0,0,20,-26,-8)"/>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-21" x="895.03125" y="20"/>
<use xlink:href="#glyph0-22" x="908.15625" y="20"/>
<use xlink:href="#glyph0-12" x="919.152344" y="20"/>
<use xlink:href="#glyph0-11" x="929.953125" y="20"/>
</g>
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-dasharray:0.4,0.4;stroke-miterlimit:10;" d="M 32.1625 4.899609 L 32.1625 3.6 L 47.061328 3.6 L 47.061328 2.235547 " transform="matrix(20,0,0,20,-26,-8)"/>
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 47.311328 2.867969 L 47.061328 2.067969 L 46.811328 2.867969 " transform="matrix(20,0,0,20,-26,-8)"/>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph1-1" x="735.457031" y="60"/>
<use xlink:href="#glyph1-11" x="743.152344" y="60"/>
<use xlink:href="#glyph1-18" x="750.847656" y="60"/>
<use xlink:href="#glyph1-4" x="758.542969" y="60"/>
<use xlink:href="#glyph1-5" x="766.238281" y="60"/>
<use xlink:href="#glyph1-19" x="773.933594" y="60"/>
<use xlink:href="#glyph1-5" x="781.628906" y="60"/>
<use xlink:href="#glyph1-6" x="789.324219" y="60"/>
</g>
<path style="fill-rule:evenodd;fill:rgb(100%,100%,100%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 24.75 18.35 L 30.372461 18.35 L 30.372461 19.75 L 24.75 19.75 Z M 24.75 18.35 " transform="matrix(20,0,0,20,-26,-8)"/>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-1" x="474.054688" y="378"/>
<use xlink:href="#glyph0-16" x="486.4375" y="378"/>
<use xlink:href="#glyph0-5" x="495.929688" y="378"/>
<use xlink:href="#glyph0-4" x="503.585938" y="378"/>
<use xlink:href="#glyph0-22" x="509.074219" y="378"/>
<use xlink:href="#glyph0-14" x="520.070312" y="378"/>
<use xlink:href="#glyph0-6" x="531.457031" y="378"/>
<use xlink:href="#glyph0-23" x="537.023438" y="378"/>
<use xlink:href="#glyph0-11" x="548.742188" y="378"/>
<use xlink:href="#glyph0-12" x="554.230469" y="378"/>
<use xlink:href="#glyph0-14" x="565.03125" y="378"/>
</g>
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-dasharray:0.4,0.4;stroke-miterlimit:10;" d="M 32.209961 12.8 L 32.209961 14.925 L 26.15 14.925 L 26.15 17.814648 " transform="matrix(20,0,0,20,-26,-8)"/>
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 25.9 17.182422 L 26.15 17.982422 L 26.4 17.182422 " transform="matrix(20,0,0,20,-26,-8)"/>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph1-20" x="522.972656" y="286.5"/>
<use xlink:href="#glyph1-5" x="530.667969" y="286.5"/>
<use xlink:href="#glyph1-12" x="538.363281" y="286.5"/>
<use xlink:href="#glyph1-5" x="546.058594" y="286.5"/>
<use xlink:href="#glyph1-15" x="553.753906" y="286.5"/>
<use xlink:href="#glyph1-16" x="561.449219" y="286.5"/>
<use xlink:href="#glyph1-8" x="569.144531" y="286.5"/>
<use xlink:href="#glyph1-5" x="576.839844" y="286.5"/>
<use xlink:href="#glyph1-6" x="584.535156" y="286.5"/>
</g>
<path style="fill-rule:evenodd;fill:rgb(100%,100%,100%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 34.1 23.55 L 37.472461 23.55 L 37.472461 24.95 L 34.1 24.95 Z M 34.1 23.55 " transform="matrix(20,0,0,20,-26,-8)"/>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-1" x="661.035156" y="482"/>
<use xlink:href="#glyph0-16" x="673.417969" y="482"/>
<use xlink:href="#glyph0-5" x="682.910156" y="482"/>
<use xlink:href="#glyph0-4" x="690.566406" y="482"/>
<use xlink:href="#glyph0-22" x="696.054688" y="482"/>
<use xlink:href="#glyph0-14" x="707.050781" y="482"/>
</g>
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 27.561328 21.047266 L 27.561328 22.15 L 35.786328 22.15 L 35.786328 23.501562 " transform="matrix(20,0,0,20,-26,-8)"/>
<path style="fill-rule:evenodd;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 27.561328 19.788672 L 27.801172 20.488672 L 27.561328 21.188672 L 27.321289 20.488672 Z M 27.561328 19.788672 " transform="matrix(20,0,0,20,-26,-8)"/>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph1-4" x="553.609375" y="431"/>
<use xlink:href="#glyph1-6" x="561.304688" y="431"/>
<use xlink:href="#glyph1-7" x="569" y="431"/>
<use xlink:href="#glyph1-11" x="576.695313" y="431"/>
<use xlink:href="#glyph1-9" x="584.390625" y="431"/>
<use xlink:href="#glyph1-17" x="592.085938" y="431"/>
<use xlink:href="#glyph1-2" x="599.78125" y="431"/>
<use xlink:href="#glyph1-9" x="607.476563" y="431"/>
<use xlink:href="#glyph1-6" x="615.171875" y="431"/>
<use xlink:href="#glyph1-5" x="622.867188" y="431"/>
<use xlink:href="#glyph1-21" x="630.5625" y="431"/>
<use xlink:href="#glyph1-7" x="638.257812" y="431"/>
<use xlink:href="#glyph1-9" x="645.953125" y="431"/>
<use xlink:href="#glyph1-13" x="653.648438" y="431"/>
</g>
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 37.472461 24.95 L 37.472461 25.85 L 43.1 25.85 L 43.1 24.25 L 37.472461 24.25 " transform="matrix(20,0,0,20,-26,-8)"/>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph1-22" x="737.402344" y="505"/>
<use xlink:href="#glyph1-5" x="745.097656" y="505"/>
<use xlink:href="#glyph1-23" x="752.792969" y="505"/>
<use xlink:href="#glyph1-8" x="760.488281" y="505"/>
<use xlink:href="#glyph1-7" x="768.183594" y="505"/>
<use xlink:href="#glyph1-16" x="775.878906" y="505"/>
<use xlink:href="#glyph1-11" x="783.574219" y="505"/>
<use xlink:href="#glyph1-8" x="791.269531" y="505"/>
<use xlink:href="#glyph1-4" x="798.964844" y="505"/>
<use xlink:href="#glyph1-9" x="806.660156" y="505"/>
<use xlink:href="#glyph1-12" x="814.355469" y="505"/>
</g>
<path style=" stroke:none;fill-rule:evenodd;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 824.074219 505 L 824.074219 497 L 832.074219 501 Z M 824.074219 505 "/>
<path style="fill-rule:evenodd;fill:rgb(100%,100%,100%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(100%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 52.1 10.95 C 52.1 11.115625 51.965625 11.25 51.8 11.25 C 51.634375 11.25 51.5 11.115625 51.5 10.95 C 51.5 10.784375 51.634375 10.65 51.8 10.65 C 51.965625 10.65 52.1 10.784375 52.1 10.95 " transform="matrix(20,0,0,20,-26,-8)"/>
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(100%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 50.6 11.55 L 53 11.55 " transform="matrix(20,0,0,20,-26,-8)"/>
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(100%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 51.8 11.25 L 51.8 12.75 " transform="matrix(20,0,0,20,-26,-8)"/>
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(100%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 51.8 12.75 L 50.6 14.05 " transform="matrix(20,0,0,20,-26,-8)"/>
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(100%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 51.8 12.75 L 53 14.05 " transform="matrix(20,0,0,20,-26,-8)"/>
<g style="fill:rgb(100%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph2-1" x="959.921875" y="296.898438"/>
<use xlink:href="#glyph2-2" x="969.824219" y="296.898438"/>
<use xlink:href="#glyph2-3" x="978.984375" y="296.898438"/>
<use xlink:href="#glyph2-4" x="992.324219" y="296.898438"/>
<use xlink:href="#glyph2-5" x="996.71875" y="296.898438"/>
<use xlink:href="#glyph2-4" x="1005.820312" y="296.898438"/>
<use xlink:href="#glyph2-6" x="1010.214844" y="296.898438"/>
<use xlink:href="#glyph2-7" x="1017.832031" y="296.898438"/>
<use xlink:href="#glyph2-8" x="1023.945312" y="296.898438"/>
<use xlink:href="#glyph2-9" x="1030.253906" y="296.898438"/>
<use xlink:href="#glyph2-7" x="1038.886719" y="296.898438"/>
<use xlink:href="#glyph2-10" x="1045" y="296.898438"/>
<use xlink:href="#glyph2-8" x="1053.789062" y="296.898438"/>
</g>
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-dasharray:0.4,0.4;stroke-miterlimit:10;" d="M 49.295898 12.75 L 41.708203 12.75 L 41.708203 12.05 L 34.055664 12.05 " transform="matrix(20,0,0,20,-26,-8)"/>
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 34.688086 11.8 L 33.888086 12.05 L 34.688086 12.3 " transform="matrix(20,0,0,20,-26,-8)"/>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph1-24" x="810.164062" y="236"/>
<use xlink:href="#glyph1-15" x="817.859375" y="236"/>
<use xlink:href="#glyph1-4" x="825.554688" y="236"/>
<use xlink:href="#glyph1-10" x="833.25" y="236"/>
<use xlink:href="#glyph1-10" x="840.945312" y="236"/>
<use xlink:href="#glyph1-5" x="848.640625" y="236"/>
<use xlink:href="#glyph1-15" x="856.335938" y="236"/>
<use xlink:href="#glyph1-6" x="864.03125" y="236"/>
</g>
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-dasharray:0.4,0.4;stroke-miterlimit:10;" d="M 51.9 9.649609 L 44.0625 9.649609 L 44.0625 5.65 L 36.160352 5.65 " transform="matrix(20,0,0,20,-26,-8)"/>
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 36.792578 5.4 L 35.992578 5.65 L 36.792578 5.9 " transform="matrix(20,0,0,20,-26,-8)"/>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph1-25" x="857.25" y="140.996094"/>
<use xlink:href="#glyph1-5" x="864.945312" y="140.996094"/>
<use xlink:href="#glyph1-13" x="872.640625" y="140.996094"/>
<use xlink:href="#glyph1-4" x="880.335938" y="140.996094"/>
<use xlink:href="#glyph1-12" x="888.03125" y="140.996094"/>
<use xlink:href="#glyph1-5" x="895.726562" y="140.996094"/>
<use xlink:href="#glyph1-6" x="903.421875" y="140.996094"/>
<use xlink:href="#glyph1-7" x="911.117188" y="140.996094"/>
<use xlink:href="#glyph1-1" x="918.8125" y="140.996094"/>
<use xlink:href="#glyph1-14" x="926.507812" y="140.996094"/>
<use xlink:href="#glyph1-21" x="934.203125" y="140.996094"/>
<use xlink:href="#glyph1-4" x="941.898438" y="140.996094"/>
<use xlink:href="#glyph1-8" x="949.59375" y="140.996094"/>
<use xlink:href="#glyph1-7" x="957.289062" y="140.996094"/>
<use xlink:href="#glyph1-11" x="964.984375" y="140.996094"/>
<use xlink:href="#glyph1-9" x="972.679688" y="140.996094"/>
<use xlink:href="#glyph1-12" x="980.375" y="140.996094"/>
<use xlink:href="#glyph1-13" x="988.070312" y="140.996094"/>
<use xlink:href="#glyph1-4" x="995.765625" y="140.996094"/>
<use xlink:href="#glyph1-10" x="1003.460938" y="140.996094"/>
<use xlink:href="#glyph1-14" x="1011.15625" y="140.996094"/>
<use xlink:href="#glyph1-15" x="1018.851562" y="140.996094"/>
<use xlink:href="#glyph1-16" x="1026.546875" y="140.996094"/>
<use xlink:href="#glyph1-8" x="1034.242188" y="140.996094"/>
<use xlink:href="#glyph1-4" x="1041.9375" y="140.996094"/>
<use xlink:href="#glyph1-9" x="1049.632812" y="140.996094"/>
<use xlink:href="#glyph1-12" x="1057.328125" y="140.996094"/>
<use xlink:href="#glyph1-7" x="1065.023438" y="140.996094"/>
<use xlink:href="#glyph1-4" x="1072.71875" y="140.996094"/>
<use xlink:href="#glyph1-12" x="1080.414062" y="140.996094"/>
</g>
<path style="fill-rule:evenodd;fill:rgb(100%,100%,100%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(100%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 5.45 1.4 C 5.45 1.565625 5.315625 1.7 5.15 1.7 C 4.984375 1.7 4.85 1.565625 4.85 1.4 C 4.85 1.234375 4.984375 1.1 5.15 1.1 C 5.315625 1.1 5.45 1.234375 5.45 1.4 " transform="matrix(20,0,0,20,-26,-8)"/>
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(100%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 3.95 2 L 6.35 2 " transform="matrix(20,0,0,20,-26,-8)"/>
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(100%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 5.15 1.7 L 5.15 3.2 " transform="matrix(20,0,0,20,-26,-8)"/>
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(100%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 5.15 3.2 L 3.95 4.5 " transform="matrix(20,0,0,20,-26,-8)"/>
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(100%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 5.15 3.2 L 6.35 4.5 " transform="matrix(20,0,0,20,-26,-8)"/>
<g style="fill:rgb(100%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph2-11" x="42.332031" y="105.898438"/>
<use xlink:href="#glyph2-12" x="51.726562" y="105.898438"/>
<use xlink:href="#glyph2-6" x="60.828125" y="105.898438"/>
<use xlink:href="#glyph2-7" x="68.445312" y="105.898438"/>
<use xlink:href="#glyph2-10" x="74.558594" y="105.898438"/>
<use xlink:href="#glyph2-3" x="83.347656" y="105.898438"/>
<use xlink:href="#glyph2-13" x="96.6875" y="105.898438"/>
<use xlink:href="#glyph2-8" x="105.359375" y="105.898438"/>
</g>
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-dasharray:0.4,0.4;stroke-miterlimit:10;" d="M 6.88418 3.2 L 15.0375 3.2 L 15.0375 6.664648 " transform="matrix(20,0,0,20,-26,-8)"/>
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 14.7875 6.032422 L 15.0375 6.832422 L 15.2875 6.032422 " transform="matrix(20,0,0,20,-26,-8)"/>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph1-26" x="123.957031" y="52"/>
<use xlink:href="#glyph1-9" x="131.652344" y="52"/>
<use xlink:href="#glyph1-12" x="139.347656" y="52"/>
<use xlink:href="#glyph1-6" x="147.042969" y="52"/>
<use xlink:href="#glyph1-14" x="154.738281" y="52"/>
<use xlink:href="#glyph1-17" x="162.433594" y="52"/>
<use xlink:href="#glyph1-5" x="170.128906" y="52"/>
<use xlink:href="#glyph1-6" x="177.824219" y="52"/>
<use xlink:href="#glyph1-7" x="185.519531" y="52"/>
<use xlink:href="#glyph1-15" x="193.214844" y="52"/>
<use xlink:href="#glyph1-5" x="200.910156" y="52"/>
<use xlink:href="#glyph1-6" x="208.605469" y="52"/>
<use xlink:href="#glyph1-9" x="216.300781" y="52"/>
<use xlink:href="#glyph1-14" x="223.996094" y="52"/>
<use xlink:href="#glyph1-15" x="231.691406" y="52"/>
<use xlink:href="#glyph1-11" x="239.386719" y="52"/>
<use xlink:href="#glyph1-5" x="247.082031" y="52"/>
<use xlink:href="#glyph1-6" x="254.777344" y="52"/>
</g>
<path style="fill-rule:evenodd;fill:rgb(100%,100%,100%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 1.35 12.9 L 6.490039 12.9 L 6.490039 14.3 L 1.35 14.3 Z M 1.35 12.9 " transform="matrix(20,0,0,20,-26,-8)"/>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-24" x="5.972656" y="269"/>
<use xlink:href="#glyph0-8" x="18.296875" y="269"/>
<use xlink:href="#glyph0-19" x="29.15625" y="269"/>
<use xlink:href="#glyph0-22" x="38.6875" y="269"/>
<use xlink:href="#glyph0-2" x="49.683594" y="269"/>
<use xlink:href="#glyph0-20" x="61.070312" y="269"/>
<use xlink:href="#glyph0-16" x="68.960938" y="269"/>
<use xlink:href="#glyph0-8" x="78.453125" y="269"/>
<use xlink:href="#glyph0-19" x="89.3125" y="269"/>
</g>
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 9.341406 7.7 L 3.919922 7.7 L 3.919922 12.9 " transform="matrix(20,0,0,20,-26,-8)"/>
<path style="fill-rule:evenodd;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 10.6 7.7 L 9.9 7.940039 L 9.2 7.7 L 9.9 7.459961 Z M 10.6 7.7 " transform="matrix(20,0,0,20,-26,-8)"/>
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-dasharray:0.4,0.4;stroke-miterlimit:10;" d="M 35.786133 24.95 L 35.786133 27 L 3.919922 27 L 3.919922 14.635352 " transform="matrix(20,0,0,20,-26,-8)"/>
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 4.169922 15.267578 L 3.919922 14.467578 L 3.669922 15.267578 " transform="matrix(20,0,0,20,-26,-8)"/>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph1-27" x="340.28125" y="528"/>
<use xlink:href="#glyph1-9" x="347.976563" y="528"/>
<use xlink:href="#glyph1-21" x="355.671875" y="528"/>
<use xlink:href="#glyph1-4" x="363.367188" y="528"/>
<use xlink:href="#glyph1-13" x="371.0625" y="528"/>
<use xlink:href="#glyph1-4" x="378.757813" y="528"/>
<use xlink:href="#glyph1-5" x="386.453125" y="528"/>
<use xlink:href="#glyph1-6" x="394.148438" y="528"/>
</g>
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-dasharray:0.4,0.4;stroke-miterlimit:10;" d="M 51.8 15.49707 L 51.8 19.05 L 30.707813 19.05 " transform="matrix(20,0,0,20,-26,-8)"/>
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 31.340039 18.8 L 30.540039 19.05 L 31.340039 19.3 " transform="matrix(20,0,0,20,-26,-8)"/>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph1-28" x="764.945312" y="369"/>
<use xlink:href="#glyph1-16" x="772.640625" y="369"/>
<use xlink:href="#glyph1-14" x="780.335938" y="369"/>
<use xlink:href="#glyph1-12" x="788.03125" y="369"/>
<use xlink:href="#glyph1-11" x="795.726562" y="369"/>
<use xlink:href="#glyph1-18" x="803.421875" y="369"/>
<use xlink:href="#glyph1-5" x="811.117188" y="369"/>
<use xlink:href="#glyph1-6" x="818.8125" y="369"/>
</g>
<path style="fill-rule:evenodd;fill:rgb(100%,100%,100%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 54.144922 2.155078 L 58.557422 2.155078 L 58.557422 3.555078 L 54.144922 3.555078 Z M 54.144922 2.155078 " transform="matrix(20,0,0,20,-26,-8)"/>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-15" x="1061.902344" y="54.101562"/>
<use xlink:href="#glyph0-5" x="1073.425781" y="54.101562"/>
<use xlink:href="#glyph0-20" x="1081.082031" y="54.101562"/>
<use xlink:href="#glyph0-12" x="1088.972656" y="54.101562"/>
<use xlink:href="#glyph0-5" x="1099.773438" y="54.101562"/>
<use xlink:href="#glyph0-8" x="1107.429688" y="54.101562"/>
<use xlink:href="#glyph0-25" x="1118.289062" y="54.101562"/>
<use xlink:href="#glyph0-26" x="1129.734375" y="54.101562"/>
</g>
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-dasharray:0.4,0.4;stroke-miterlimit:10;" d="M 48.322461 1.15 L 51.008594 1.15 L 51.008594 2.855078 L 53.760742 2.855078 " transform="matrix(20,0,0,20,-26,-8)"/>
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 53.12832 3.105078 L 53.92832 2.855078 L 53.12832 2.605078 " transform="matrix(20,0,0,20,-26,-8)"/>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph1-14" x="996.171875" y="28.050781"/>
<use xlink:href="#glyph1-6" x="1003.867188" y="28.050781"/>
<use xlink:href="#glyph1-5" x="1011.5625" y="28.050781"/>
<use xlink:href="#glyph1-6" x="1019.257812" y="28.050781"/>
</g>
<path style="fill:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 27.561328 21.058594 L 27.561328 22.15 L 19.345703 22.15 L 19.345703 23.652734 " transform="matrix(20,0,0,20,-26,-8)"/>
<path style="fill-rule:evenodd;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 27.561328 19.8 L 27.801172 20.5 L 27.561328 21.2 L 27.321289 20.5 Z M 27.561328 19.8 " transform="matrix(20,0,0,20,-26,-8)"/>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph1-4" x="389.203125" y="431"/>
<use xlink:href="#glyph1-6" x="396.898438" y="431"/>
<use xlink:href="#glyph1-7" x="404.59375" y="431"/>
<use xlink:href="#glyph1-11" x="412.289062" y="431"/>
<use xlink:href="#glyph1-9" x="419.984375" y="431"/>
<use xlink:href="#glyph1-17" x="427.679688" y="431"/>
<use xlink:href="#glyph1-2" x="435.375" y="431"/>
<use xlink:href="#glyph1-9" x="443.070312" y="431"/>
<use xlink:href="#glyph1-6" x="450.765625" y="431"/>
<use xlink:href="#glyph1-5" x="458.460938" y="431"/>
<use xlink:href="#glyph1-21" x="466.15625" y="431"/>
<use xlink:href="#glyph1-7" x="473.851562" y="431"/>
<use xlink:href="#glyph1-9" x="481.546875" y="431"/>
<use xlink:href="#glyph1-13" x="489.242188" y="431"/>
</g>
<path style="fill-rule:evenodd;fill:rgb(100%,100%,100%);fill-opacity:1;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;" d="M 15.201953 23.652734 L 23.489453 23.652734 L 23.489453 25.052734 L 15.201953 25.052734 Z M 15.201953 23.652734 " transform="matrix(20,0,0,20,-26,-8)"/>
<g style="fill:rgb(0%,0%,0%);fill-opacity:1;">
<use xlink:href="#glyph0-27" x="283.082031" y="484.054688"/>
<use xlink:href="#glyph0-28" x="294.019531" y="484.054688"/>
<use xlink:href="#glyph0-16" x="311.871094" y="484.054688"/>
<use xlink:href="#glyph0-12" x="321.363281" y="484.054688"/>
<use xlink:href="#glyph0-16" x="332.164062" y="484.054688"/>
<use xlink:href="#glyph0-26" x="341.65625" y="484.054688"/>
<use xlink:href="#glyph0-6" x="352.085938" y="484.054688"/>
<use xlink:href="#glyph0-29" x="357.652344" y="484.054688"/>
<use xlink:href="#glyph0-14" x="363.609375" y="484.054688"/>
<use xlink:href="#glyph0-3" x="374.996094" y="484.054688"/>
<use xlink:href="#glyph0-4" x="386.441406" y="484.054688"/>
<use xlink:href="#glyph0-16" x="391.929688" y="484.054688"/>
<use xlink:href="#glyph0-12" x="401.421875" y="484.054688"/>
<use xlink:href="#glyph0-5" x="412.222656" y="484.054688"/>
<use xlink:href="#glyph0-22" x="419.878906" y="484.054688"/>
<use xlink:href="#glyph0-20" x="430.875" y="484.054688"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

View File

@@ -56,7 +56,9 @@ Getting Started
dev/devstack
deploy/configuration
deploy/conf-files
dev/notifications
dev/testing
dev/rally_link
API References
--------------
@@ -73,7 +75,10 @@ Plugins
:maxdepth: 1
dev/plugin/base-setup
dev/plugin/goal-plugin
dev/plugin/scoring-engine-plugin
dev/plugin/strategy-plugin
dev/plugin/cdmc-plugin
dev/plugin/action-plugin
dev/plugin/planner-plugin
dev/plugins
@@ -90,6 +95,9 @@ Introduction
deploy/installation
deploy/user-guide
deploy/policy
deploy/gmr
strategies/strategies
Watcher Manual Pages
====================

View File

@@ -0,0 +1,99 @@
==================================
Basic Offline Server Consolidation
==================================
Synopsis
--------
**display name**: ``basic``
**goal**: ``server_consolidation``
.. watcher-term:: watcher.decision_engine.strategy.strategies.basic_consolidation
Requirements
------------
Metrics
*******
The *basic* strategy requires the following metrics:
============================ ============ ======= =======
metric service name plugins comment
============================ ============ ======= =======
``compute.node.cpu.percent`` ceilometer_ none
``cpu_util`` ceilometer_ none
============================ ============ ======= =======
.. _ceilometer: http://docs.openstack.org/admin-guide/telemetry-measurements.html#openstack-compute
Cluster data model
******************
Default Watcher's Compute cluster data model:
.. watcher-term:: watcher.decision_engine.model.collector.nova.NovaClusterDataModelCollector
Actions
*******
Default Watcher's actions:
.. list-table::
:widths: 30 30
:header-rows: 1
* - action
- description
* - ``migration``
- .. watcher-term:: watcher.applier.actions.migration.Migrate
* - ``change_nova_service_state``
- .. watcher-term:: watcher.applier.actions.change_nova_service_state.ChangeNovaServiceState
Planner
*******
Default Watcher's planner:
.. watcher-term:: watcher.decision_engine.planner.default.DefaultPlanner
Configuration
-------------
Strategy parameter is:
====================== ====== ============= ===================================
parameter type default Value description
====================== ====== ============= ===================================
``migration_attempts`` Number 0 Maximum number of combinations to
be tried by the strategy while
searching for potential candidates.
To remove the limit, set it to 0
``period`` Number 7200 The time interval in seconds
for getting statistic aggregation
from metric data source
====================== ====== ============= ===================================
Efficacy Indicator
------------------
.. watcher-func::
:format: literal_block
watcher.decision_engine.goal.efficacy.specs.ServerConsolidation.get_global_efficacy_indicator
How to use it ?
---------------
.. code-block:: shell
$ openstack optimize audittemplate create \
at1 server_consolidation --strategy basic
$ openstack optimize audit create -a at1 -p migration_attempts=4
External Links
--------------
None.

View File

@@ -0,0 +1,101 @@
=================================
Outlet Temperature Based Strategy
=================================
Synopsis
--------
**display name**: ``outlet_temperature``
**goal**: ``thermal_optimization``
Outlet (Exhaust Air) temperature is a new thermal telemetry which can be
used to measure the host's thermal/workload status. This strategy makes
decisions to migrate workloads to the hosts with good thermal condition
(lowest outlet temperature) when the outlet temperature of source hosts
reach a configurable threshold.
Requirements
------------
This strategy has a dependency on the host having Intel's Power
Node Manager 3.0 or later enabled.
Metrics
*******
The *outlet_temperature* strategy requires the following metrics:
========================================= ============ ======= =======
metric service name plugins comment
========================================= ============ ======= =======
``hardware.ipmi.node.outlet_temperature`` ceilometer_ IPMI
========================================= ============ ======= =======
.. _ceilometer: http://docs.openstack.org/admin-guide/telemetry-measurements.html#ipmi-based-meters
Cluster data model
******************
Default Watcher's Compute cluster data model:
.. watcher-term:: watcher.decision_engine.model.collector.nova.NovaClusterDataModelCollector
Actions
*******
Default Watcher's actions:
.. list-table::
:widths: 30 30
:header-rows: 1
* - action
- description
* - ``migration``
- .. watcher-term:: watcher.applier.actions.migration.Migrate
Planner
*******
Default Watcher's planner:
.. watcher-term:: watcher.decision_engine.planner.default.DefaultPlanner
Configuration
-------------
Strategy parameter is:
============== ====== ============= ====================================
parameter type default Value description
============== ====== ============= ====================================
``threshold`` Number 35.0 Temperature threshold for migration
============== ====== ============= ====================================
Efficacy Indicator
------------------
None
Algorithm
---------
For more information on the Outlet Temperature Based Strategy please refer to:
https://specs.openstack.org/openstack/watcher-specs/specs/mitaka/implemented/outlet-temperature-based-strategy.html
How to use it ?
---------------
.. code-block:: shell
$ openstack optimize audittemplate create \
at1 thermal_optimization --strategy outlet_temperature
$ openstack optimize audit create -a at1 -p threshold=31.0
External Links
--------------
- `Intel Power Node Manager 3.0 <http://www.intel.com/content/www/us/en/power-management/intelligent-power-node-manager-3-0-specification.html>`_

View File

@@ -0,0 +1,8 @@
Strategies
==========
.. toctree::
:glob:
:maxdepth: 1
./*

View File

@@ -0,0 +1,115 @@
=============
Strategy name
=============
Synopsis
--------
**display name**:
**goal**:
Add here a complete description of your strategy
Requirements
------------
Metrics
*******
Write here the list of metrics required by your strategy algorithm (in the form
of a table). If these metrics requires specific Telemetry plugin or other
additional software, please explain here how to deploy them (and add link to
dedicated installation guide).
Example:
======================= ============ ======= =======
metric service name plugins comment
======================= ============ ======= =======
compute.node.* ceilometer_ none one point every 60s
vm.cpu.utilization_perc monasca_ none
power ceilometer_ kwapi_ one point every 60s
======================= ============ ======= =======
.. _ceilometer: http://docs.openstack.org/admin-guide/telemetry-measurements.html#openstack-compute
.. _monasca: https://github.com/openstack/monasca-agent/blob/master/docs/Libvirt.md
.. _kwapi: https://kwapi.readthedocs.io/en/latest/index.html
Cluster data model
******************
Default Watcher's cluster data model.
or
If your strategy implementation requires a new cluster data model, please
describe it in this section, with a link to model plugin's installation guide.
Actions
*******
Default Watcher's actions.
or
If your strategy implementation requires new actions, add the list of Action
plugins here (in the form of a table) with a link to the plugin's installation
procedure.
======== =================
action description
======== =================
action1_ This action1 ...
action2_ This action2 ...
======== =================
.. _action1 : https://github.com/myrepo/watcher/plugins/action1
.. _action2 : https://github.com/myrepo/watcher/plugins/action2
Planner
*******
Default Watcher's planner.
or
If your strategy requires also a new planner to schedule built actions in time,
please describe it in this section, with a link to planner plugin's
installation guide.
Configuration
-------------
If your strategy use configurable parameters, explain here how to tune them.
Efficacy Indicator
------------------
Add here the Efficacy indicator computed by your strategy.
Algorithm
---------
Add here either the description of your algorithm or
link to the existing description.
How to use it ?
---------------
.. code-block:: shell
$ Write the command line to create an audit with your strategy.
External Links
--------------
If you have written papers, blog articles .... about your strategy into Watcher,
or if your strategy is based from external publication(s), please add HTTP
links and references in this section.
- `link1 <http://www.link1.papers.com>`_
- `link2 <http://www.link2.papers.com>`_

View File

@@ -0,0 +1,107 @@
==================================
Uniform Airflow Migration Strategy
==================================
Synopsis
--------
**display name**: ``uniform_airflow``
**goal**: ``airflow_optimization``
.. watcher-term:: watcher.decision_engine.strategy.strategies.uniform_airflow
Requirements
------------
This strategy has a dependency on the server having Intel's Power
Node Manager 3.0 or later enabled.
Metrics
*******
The *uniform_airflow* strategy requires the following metrics:
================================== ============ ======= =======
metric service name plugins comment
================================== ============ ======= =======
``hardware.ipmi.node.airflow`` ceilometer_ IPMI
``hardware.ipmi.node.temperature`` ceilometer_ IPMI
``hardware.ipmi.node.power`` ceilometer_ IPMI
================================== ============ ======= =======
.. _ceilometer: http://docs.openstack.org/admin-guide/telemetry-measurements.html#ipmi-based-meters
Cluster data model
******************
Default Watcher's Compute cluster data model:
.. watcher-term:: watcher.decision_engine.model.collector.nova.NovaClusterDataModelCollector
Actions
*******
Default Watcher's actions:
.. list-table::
:widths: 30 30
:header-rows: 1
* - action
- description
* - ``migration``
- .. watcher-term:: watcher.applier.actions.migration.Migrate
Planner
*******
Default Watcher's planner:
.. watcher-term:: watcher.decision_engine.planner.default.DefaultPlanner
Configuration
-------------
Strategy parameters are:
====================== ====== ============= ===========================
parameter type default Value description
====================== ====== ============= ===========================
``threshold_airflow`` Number 400.0 Airflow threshold for
migration Unit is 0.1CFM
``threshold_inlet_t`` Number 28.0 Inlet temperature threshold
for migration decision
``threshold_power`` Number 350.0 System power threshold for
migration decision
``period`` Number 300 Aggregate time period of
ceilometer
====================== ====== ============= ===========================
Efficacy Indicator
------------------
None
Algorithm
---------
For more information on the Uniform Airflow Migration Strategy please refer to:
https://specs.openstack.org/openstack/watcher-specs/specs/newton/implemented/uniform-airflow-migration-strategy.html
How to use it ?
---------------
.. code-block:: shell
$ openstack optimize audittemplate create \
at1 airflow_optimization --strategy uniform_airflow
$ openstack optimize audit create -a at1 -p threshold_airflow=410 \
-p threshold_inlet_t=29.0 -p threshold_power=355.0 -p period=310
External Links
--------------
- `Intel Power Node Manager 3.0 <http://www.intel.com/content/www/us/en/power-management/intelligent-power-node-manager-3-0-specification.html>`_

View File

@@ -0,0 +1,100 @@
==================================
VM Workload Consolidation Strategy
==================================
Synopsis
--------
**display name**: ``vm_workload_consolidation``
**goal**: ``vm_consolidation``
.. watcher-term:: watcher.decision_engine.strategy.strategies.vm_workload_consolidation
Requirements
------------
Metrics
*******
The *vm_workload_consolidation* strategy requires the following metrics:
============================ ============ ======= =======
metric service name plugins comment
============================ ============ ======= =======
``memory`` ceilometer_ none
``disk.root.size`` ceilometer_ none
============================ ============ ======= =======
The following metrics are not required but increase the accuracy of
the strategy if available:
============================ ============ ======= =======
metric service name plugins comment
============================ ============ ======= =======
``memory.usage`` ceilometer_ none
``cpu_util`` ceilometer_ none
============================ ============ ======= =======
.. _ceilometer: http://docs.openstack.org/admin-guide/telemetry-measurements.html#openstack-compute
Cluster data model
******************
Default Watcher's Compute cluster data model:
.. watcher-term:: watcher.decision_engine.model.collector.nova.NovaClusterDataModelCollector
Actions
*******
Default Watcher's actions:
.. list-table::
:widths: 30 30
:header-rows: 1
* - action
- description
* - ``migration``
- .. watcher-term:: watcher.applier.actions.migration.Migrate
* - ``change_nova_service_state``
- .. watcher-term:: watcher.applier.actions.change_nova_service_state.ChangeNovaServiceState
Planner
*******
Default Watcher's planner:
.. watcher-term:: watcher.decision_engine.planner.default.DefaultPlanner
Efficacy Indicator
------------------
.. watcher-func::
:format: literal_block
watcher.decision_engine.goal.efficacy.specs.ServerConsolidation.get_global_efficacy_indicator
Algorithm
---------
For more information on the VM Workload consolidation strategy please refer to: https://specs.openstack.org/openstack/watcher-specs/specs/mitaka/implemented/zhaw-load-consolidation.html
How to use it ?
---------------
.. code-block:: shell
$ openstack optimize audittemplate create \
at1 server_consolidation --strategy vm_workload_consolidation
$ openstack optimize audit create -a at1
External Links
--------------
*Spec URL*
https://specs.openstack.org/openstack/watcher-specs/specs/mitaka/implemented/zhaw-load-consolidation.html

View File

@@ -0,0 +1,141 @@
=============================================
Watcher Overload standard deviation algorithm
=============================================
Synopsis
--------
**display name**: ``workload_stabilization``
**goal**: ``workload_balancing``
.. watcher-term:: watcher.decision_engine.strategy.strategies.workload_stabilization
Requirements
------------
Metrics
*******
The *workload_stabilization* strategy requires the following metrics:
============================ ============ ======= =======
metric service name plugins comment
============================ ============ ======= =======
``compute.node.cpu.percent`` ceilometer_ none
``hardware.memory.used`` ceilometer_ SNMP_
``cpu_util`` ceilometer_ none
``memory.resident`` ceilometer_ none
============================ ============ ======= =======
.. _ceilometer: http://docs.openstack.org/admin-guide/telemetry-measurements.html#openstack-compute
.. _SNMP: http://docs.openstack.org/admin-guide/telemetry-measurements.html
Cluster data model
******************
Default Watcher's Compute cluster data model:
.. watcher-term:: watcher.decision_engine.model.collector.nova.NovaClusterDataModelCollector
Actions
*******
Default Watcher's actions:
.. list-table::
:widths: 30 30
:header-rows: 1
* - action
- description
* - ``migration``
- .. watcher-term:: watcher.applier.actions.migration.Migrate
Planner
*******
Default Watcher's planner:
.. watcher-term:: watcher.decision_engine.planner.default.DefaultPlanner
Configuration
-------------
Strategy parameters are:
==================== ====== ===================== =============================
parameter type default Value description
==================== ====== ===================== =============================
``metrics`` array |metrics| Metrics used as rates of
cluster loads.
``thresholds`` object |thresholds| Dict where key is a metric
and value is a trigger value.
``weights`` object |weights| These weights used to
calculate common standard
deviation. Name of weight
contains meter name and
_weight suffix.
``instance_metrics`` object |instance_metrics| Mapping to get hardware
statistics using instance
metrics.
``host_choice`` string retry Method of host's choice.
There are cycle, retry and
fullsearch methods. Cycle
will iterate hosts in cycle.
Retry will get some hosts
random (count defined in
retry_count option).
Fullsearch will return each
host from list.
``retry_count`` number 1 Count of random returned
hosts.
``periods`` object |periods| These periods are used to get
statistic aggregation for
instance and host metrics.
The period is simply a
repeating interval of time
into which the samples are
grouped for aggregation.
Watcher uses only the last
period of all recieved ones.
==================== ====== ===================== =============================
.. |metrics| replace:: ["cpu_util", "memory.resident"]
.. |thresholds| replace:: {"cpu_util": 0.2, "memory.resident": 0.2}
.. |weights| replace:: {"cpu_util_weight": 1.0, "memory.resident_weight": 1.0}
.. |instance_metrics| replace:: {"cpu_util": "compute.node.cpu.percent", "memory.resident": "hardware.memory.used"}
.. |periods| replace:: {"instance": 720, "node": 600}
Efficacy Indicator
------------------
.. watcher-func::
:format: literal_block
watcher.decision_engine.goal.efficacy.specs.ServerConsolidation.get_global_efficacy_indicator
Algorithm
---------
You can find description of overload algorithm and role of standard deviation
here: https://specs.openstack.org/openstack/watcher-specs/specs/newton/implemented/sd-strategy.html
How to use it ?
---------------
.. code-block:: shell
$ openstack optimize audittemplate create \
at1 workload_balancing --strategy workload_stabilization
$ openstack optimize audit create -a at1 \
-p thresholds='{"memory.resident": 0.05}' \
-p metrics='["memory.resident"]'
External Links
--------------
- `Watcher Overload standard deviation algorithm spec <https://specs.openstack.org/openstack/watcher-specs/specs/newton/implemented/sd-strategy.html>`_

View File

@@ -0,0 +1,98 @@
===================================
Workload Balance Migration Strategy
===================================
Synopsis
--------
**display name**: ``workload_balance``
**goal**: ``workload_balancing``
.. watcher-term:: watcher.decision_engine.strategy.strategies.workload_balance
Requirements
------------
None.
Metrics
*******
The *workload_balance* strategy requires the following metrics:
======================= ============ ======= =======
metric service name plugins comment
======================= ============ ======= =======
``cpu_util`` ceilometer_ none
======================= ============ ======= =======
.. _ceilometer: http://docs.openstack.org/admin-guide/telemetry-measurements.html#openstack-compute
Cluster data model
******************
Default Watcher's Compute cluster data model:
.. watcher-term:: watcher.decision_engine.model.collector.nova.NovaClusterDataModelCollector
Actions
*******
Default Watcher's actions:
.. list-table::
:widths: 30 30
:header-rows: 1
* - action
- description
* - ``migration``
- .. watcher-term:: watcher.applier.actions.migration.Migrate
Planner
*******
Default Watcher's planner:
.. watcher-term:: watcher.decision_engine.planner.default.DefaultPlanner
Configuration
-------------
Strategy parameters are:
============== ====== ============= ====================================
parameter type default Value description
============== ====== ============= ====================================
``threshold`` Number 25.0 Workload threshold for migration
``period`` Number 300 Aggregate time period of ceilometer
============== ====== ============= ====================================
Efficacy Indicator
------------------
None
Algorithm
---------
For more information on the Workload Balance Migration Strategy please refer
to: https://specs.openstack.org/openstack/watcher-specs/specs/mitaka/implemented/workload-balance-migration-strategy.html
How to use it ?
---------------
.. code-block:: shell
$ openstack optimize audittemplate create \
at1 workload_balancing --strategy workload_balance
$ openstack optimize audit create -a at1 -p threshold=26.0 \
-p period=310
External Links
--------------
None.

View File

@@ -1,4 +1,4 @@
To generate the sample watcher.conf file, run the following
command from the top level of the watcher directory:
tox -econfig
tox -e genconfig

View File

@@ -1,5 +1,45 @@
{
"admin_api": "role:admin or role:administrator",
"show_password": "!",
"default": "rule:admin_api"
"default": "rule:admin_api",
"action:detail": "rule:default",
"action:get": "rule:default",
"action:get_all": "rule:default",
"action_plan:delete": "rule:default",
"action_plan:detail": "rule:default",
"action_plan:get": "rule:default",
"action_plan:get_all": "rule:default",
"action_plan:update": "rule:default",
"audit:create": "rule:default",
"audit:delete": "rule:default",
"audit:detail": "rule:default",
"audit:get": "rule:default",
"audit:get_all": "rule:default",
"audit:update": "rule:default",
"audit_template:create": "rule:default",
"audit_template:delete": "rule:default",
"audit_template:detail": "rule:default",
"audit_template:get": "rule:default",
"audit_template:get_all": "rule:default",
"audit_template:update": "rule:default",
"goal:detail": "rule:default",
"goal:get": "rule:default",
"goal:get_all": "rule:default",
"scoring_engine:detail": "rule:default",
"scoring_engine:get": "rule:default",
"scoring_engine:get_all": "rule:default",
"strategy:detail": "rule:default",
"strategy:get": "rule:default",
"strategy:get_all": "rule:default",
"service:detail": "rule:default",
"service:get": "rule:default",
"service:get_all": "rule:default"
}

View File

@@ -4,6 +4,13 @@ wrap_width = 79
namespace = watcher
namespace = keystonemiddleware.auth_token
namespace = oslo.log
namespace = oslo.cache
namespace = oslo.concurrency
namespace = oslo.db
namespace = oslo.log
namespace = oslo.messaging
namespace = oslo.policy
namespace = oslo.reports
namespace = oslo.service.periodic_task
namespace = oslo.service.service
namespace = oslo.service.wsgi

42
rally-jobs/README.rst Normal file
View File

@@ -0,0 +1,42 @@
Rally job
=========
We provide, with Watcher, a Rally plugin you can use to benchmark the optimization service.
To launch this task with configured Rally you just need to run:
::
rally task start watcher/rally-jobs/watcher-watcher.yaml
Structure
---------
* plugins - directory where you can add rally plugins. Almost everything in
Rally is a plugin. Benchmark context, Benchmark scenario, SLA checks, Generic
cleanup resources, ....
* extra - all files from this directory will be copy pasted to gates, so you
are able to use absolute paths in rally tasks.
Files will be located in ~/.rally/extra/*
* watcher.yaml is a task that is run in gates against OpenStack
deployed by DevStack
Useful links
------------
* How to install: http://docs.openstack.org/developer/rally/install.html
* How to set Rally up and launch your first scenario: https://rally.readthedocs.io/en/latest/tutorial/step_1_setting_up_env_and_running_benchmark_from_samples.html
* More about Rally: https://rally.readthedocs.org/en/latest/
* Rally release notes: https://rally.readthedocs.org/en/latest/release_notes.html
* How to add rally-gates: https://rally.readthedocs.org/en/latest/gates.html
* About plugins: https://rally.readthedocs.org/en/latest/plugins.html
* Plugin samples: https://github.com/openstack/rally/tree/master/samples/plugins

View File

@@ -0,0 +1,63 @@
---
Watcher.create_audit_and_delete:
-
runner:
type: "constant"
times: 10
concurrency: 2
context:
users:
tenants: 2
users_per_tenant: 2
audit_templates:
audit_templates_per_admin: 5
fill_strategy: "round_robin"
params:
- goal:
name: "dummy"
strategy:
name: "dummy"
sla:
failure_rate:
max: 0
Watcher.create_audit_template_and_delete:
-
args:
goal:
name: "dummy"
strategy:
name: "dummy"
runner:
type: "constant"
times: 10
concurrency: 2
sla:
failure_rate:
max: 0
Watcher.list_audit_templates:
-
runner:
type: "constant"
times: 10
concurrency: 2
context:
users:
tenants: 2
users_per_tenant: 2
audit_templates:
audit_templates_per_admin: 5
fill_strategy: "random"
params:
- goal:
name: "workload_balancing"
strategy:
name: "workload_stabilization"
- goal:
name: "dummy"
strategy:
name: "dummy"
sla:
failure_rate:
max: 0

View File

@@ -0,0 +1,8 @@
---
features:
- Added a standard way to both declare and fetch
configuration options so that whenever the
administrator generates the Watcher
configuration sample file, it contains the
configuration options of the plugins that are
currently available.

View File

@@ -0,0 +1,7 @@
---
features:
- Added a generic scoring engine module, which
will standardize interactions with scoring engines
through the common API. It is possible to use the
scoring engine by different Strategies, which
improve the code and data model re-use.

View File

@@ -0,0 +1,3 @@
---
features:
- Add notifications related to Audit object.

View File

@@ -0,0 +1,5 @@
---
features:
- Watcher can continuously optimize the OpenStack cloud for a specific
strategy or goal by triggering an audit periodically which generates
an action plan and run it automatically.

View File

@@ -0,0 +1,3 @@
---
features:
- Centralize all configuration options for Watcher.

View File

@@ -0,0 +1,6 @@
---
features:
- Added an in-memory cache of the cluster model
built up and kept fresh via notifications from
services of interest in addition to periodic
syncing logic.

View File

@@ -0,0 +1,4 @@
---
features:
- Added a way to add a new action without having to
amend the source code of the default planner.

View File

@@ -0,0 +1,4 @@
---
features:
- Added a way to create periodic audit to be able to
optimize continuously the cloud infrastructure.

View File

@@ -0,0 +1,3 @@
---
features:
- Watcher database can now be upgraded thanks to Alembic.

View File

@@ -0,0 +1,5 @@
---
features:
- Provides a generic way to define the scope of an audit. The set of audited
resources will be called "Audit scope" and will be defined in each audit
template (which contains the audit settings).

View File

@@ -0,0 +1,4 @@
---
features:
- Added a way to compare the efficacy of different
strategies for a give optimization goal.

View File

@@ -0,0 +1,5 @@
---
features:
- Added a way to return the of available goals depending
on which strategies have been deployed on the node
where the decision engine is running.

View File

@@ -0,0 +1,6 @@
---
features:
- The graph model describes how VMs are associated to compute hosts.
This allows for seeing relationships upfront between the entities and hence
can be used to identify hot/cold spots in the data center and influence
a strategy decision.

View File

@@ -0,0 +1,4 @@
---
features:
- Watcher supports multiple metrics backend and relies on Ceilometer and
Monasca.

View File

@@ -0,0 +1,5 @@
---
features:
- Allow decision engine to pass strategy parameters,
like optimization threshold, to selected strategy,
also strategy to provide parameters info to end user.

View File

@@ -0,0 +1,6 @@
---
features:
- Copy all audit templates parameters into
audit instead of having a reference to the
audit template.

View File

@@ -0,0 +1,4 @@
---
features:
- Watcher can now run specific actions in parallel improving the performances
dramatically when executing an action plan.

View File

@@ -0,0 +1,4 @@
---
features:
- Add superseded state for an action plan if the cluster data model has
changed after it has been created.

View File

@@ -0,0 +1,7 @@
---
features:
- Added a strategy that monitors if there is a higher
load on some hosts compared to other hosts in the
cluster and re-balances the work across hosts to
minimize the standard deviation of the loads in
the cluster.

View File

@@ -0,0 +1,5 @@
---
features:
- Added a new strategy based on the airflow
of servers. This strategy makes decisions
to migrate VMs to make the airflow uniform.

View File

@@ -0,0 +1,8 @@
---
features:
- Provide a notification mechanism into Watcher that supports versioning.
Whenever a Watcher object is created, updated or deleted, a versioned
notification will, if it's relevant, be automatically sent to notify in order
to allow an event-driven style of architecture within Watcher. Moreover, it
will also give other services and/or 3rd party softwares (e.g. monitoring
solutions or rules engines) the ability to react to such events.

View File

@@ -0,0 +1,4 @@
---
features:
- Added policies to handle user rights
to access Watcher API.

View File

@@ -0,0 +1,3 @@
---
features:
- Add a service supervisor to watch Watcher deamons.

View File

@@ -0,0 +1,5 @@
---
features:
- all Watcher objects have been refactored to support OVO
(oslo.versionedobjects) which was a prerequisite step in order to implement
versioned notifications.

View File

@@ -0,0 +1,7 @@
---
features:
- Added a strategy based on the VM workloads of
hypervisors. This strategy makes decisions to
migrate workloads to make the total VM workloads
of each hypervisor balanced, when the total VM
workloads of hypervisor reaches threshold.

Some files were not shown because too many files have changed in this diff Show More