Compare commits

..

158 Commits

Author SHA1 Message Date
Jenkins
62cb8a8d29 Merge "Add release note for action plan notifications" 2017-02-02 17:46:18 +00:00
Jenkins
50e5e86c75 Merge "Added action_plan.execution.* actions" 2017-02-02 17:44:52 +00:00
Jenkins
e3dd5c2a7e Merge "Added action_plan.create|update|delete notifs" 2017-02-02 17:44:08 +00:00
Jenkins
630c2cbb79 Merge "Updated graph model to use attr_dict" 2017-02-02 17:25:52 +00:00
Vincent Françoise
d49c6c16a6 Added action_plan.execution.* actions
Partially Implements: blueprint action-plan-versioned-notifications-api

Change-Id: I9bd346c19f1cafcaa720de554fd9c056c76de050
2017-02-02 18:05:26 +01:00
Vincent Françoise
e51e7e4317 Added action_plan.create|update|delete notifs
In this changeset, I added 3 notifications:

- action_plan.create
- action_plan.update
- action_plan.delete

Partially Implements: blueprint action-plan-versioned-notifications-api

Change-Id: I8821fc6f47e7486037839d81bed9e28020b02fdd
2017-02-02 18:05:24 +01:00
Antoine Cabot
244d28afa6 Add release note for action plan notifications
Change-Id: I7670e8866835b099a2f6d91b4c486e1056d52a97
2017-02-02 17:35:07 +01:00
David TARDIVEL
7ac1d0d048 Add first alembic version for db migration
Alembic provides command script to update a relational
database, using SQLAlchemy. I provide in this patchset the
initial version python script for create a Ocata db version.

Implements: blueprint db-migration

Change-Id: I7bda4286bc8141bb4fcfba3837070966ef506b5d
2017-02-01 14:40:11 +01:00
Vincent Françoise
52d701a56e Updated graph model to use attr_dict
This patchset makes use of a more idiomatic structure of networkx

Change-Id: Iccc4e9f0cc14cccadb2959ff8d68cd68367c4da3
2017-01-31 12:15:45 +01:00
Vincent Françoise
ea1fd5967a Fix context error for user
In this changeset, I fixed an error in the Watcher RequestContext
that was introduced by the release of oslo.context==2.12.X which
makes user_id an alias of user (among others)
https://github.com/openstack/oslo.context/blob/2.12.1/oslo_context/context.py#L258-L269

Change-Id: I4e35c675de7ee01db90f700eece0b28413b34c47
2017-01-31 11:07:03 +01:00
Jenkins
547bf0529f Merge "Fix multinode tempest test failure" 2017-01-27 15:31:02 +00:00
Vincent Françoise
659cbf3207 Idiomatic loop for calculate_num_migrations
Change-Id: Iddcb6dfbed2d2793df9c33408858f1a8d4600d10
2017-01-27 14:59:44 +01:00
Jenkins
eb5a362287 Merge "Documentation update" 2017-01-27 09:53:02 +00:00
Vincent Françoise
198d827645 Fix multinode tempest test failure
Change-Id: Ibb5cbb93d53ff45d66ab4f0c0d4b12e908170d35
2017-01-26 17:35:55 +01:00
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
David TARDIVEL
59c5adc8ad Documentation update
Here is a new architecture diagram with some updates on the
glossary and on descriptions of architecture elements.
I also fix some warning logs.

Closes-Bug: #1657405
Change-Id: I442082d702fc8667e9397c090da51ca1ead5d86e
2017-01-25 13:10:56 +01: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
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
244 changed files with 9863 additions and 3683 deletions

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:

View File

@@ -129,6 +129,7 @@ function create_watcher_conf {
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"
@@ -187,7 +188,7 @@ function init_watcher {
recreate_database watcher
# Create watcher schema
$WATCHER_BIN_DIR/watcher-db-manage --config-file $WATCHER_CONF create_schema
$WATCHER_BIN_DIR/watcher-db-manage --config-file $WATCHER_CONF upgrade head
fi
create_watcher_cache_dir
}

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

@@ -45,3 +45,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

@@ -1,4 +1,3 @@
# -*- encoding: utf-8 -*-
# Copyright (c) 2015 b<>com
#
# Licensed under the Apache License, Version 2.0 (the "License");

View File

@@ -0,0 +1,54 @@
{
"publisher_id": "infra-optim:node0",
"payload": {
"watcher_object.version": "1.0",
"watcher_object.data": {
"strategy_uuid": "cb3d0b58-4415-4d90-b75b-1e96878730e3",
"strategy": {
"watcher_object.version": "1.0",
"watcher_object.data": {
"uuid": "cb3d0b58-4415-4d90-b75b-1e96878730e3",
"display_name": "test strategy",
"name": "TEST",
"updated_at": null,
"parameters_spec": {},
"created_at": "2016-10-18T09:52:05Z",
"deleted_at": null
},
"watcher_object.namespace": "watcher",
"watcher_object.name": "StrategyPayload"
},
"created_at": null,
"audit_uuid": "10a47dd1-4874-4298-91cf-eff046dbdb8d",
"audit": {
"watcher_object.version": "1.0",
"watcher_object.data": {
"audit_type": "ONESHOT",
"scope": [],
"uuid": "10a47dd1-4874-4298-91cf-eff046dbdb8d",
"goal_uuid": "bc830f84-8ae3-4fc6-8bc6-e3dd15e8b49a",
"strategy_uuid": "75234dfe-87e3-4f11-a0e0-3c3305d86a39",
"parameters": {},
"interval": null,
"deleted_at": null,
"state": "PENDING",
"created_at": "2016-10-18T09:52:05Z",
"updated_at": null
},
"watcher_object.namespace": "watcher",
"watcher_object.name": "TerseAuditPayload"
},
"uuid": "76be87bd-3422-43f9-93a0-e85a577e3061",
"global_efficacy": {},
"deleted_at": null,
"state": "RECOMMENDED",
"updated_at": null
},
"watcher_object.namespace": "watcher",
"watcher_object.name": "ActionPlanCreatePayload"
},
"priority": "INFO",
"message_id": "5148bff1-ea06-4ad6-8e4e-8c85ca5eb629",
"event_type": "action_plan.create",
"timestamp": "2016-10-18 09:52:05.219414"
}

View File

@@ -0,0 +1,54 @@
{
"publisher_id": "infra-optim:node0",
"timestamp": "2016-10-18 09:52:05.219414",
"payload": {
"watcher_object.data": {
"uuid": "76be87bd-3422-43f9-93a0-e85a577e3061",
"created_at": "2016-10-18T09:52:05Z",
"audit_uuid": "10a47dd1-4874-4298-91cf-eff046dbdb8d",
"audit": {
"watcher_object.data": {
"uuid": "10a47dd1-4874-4298-91cf-eff046dbdb8d",
"goal_uuid": "bc830f84-8ae3-4fc6-8bc6-e3dd15e8b49a",
"strategy_uuid": "75234dfe-87e3-4f11-a0e0-3c3305d86a39",
"interval": null,
"audit_type": "ONESHOT",
"scope": [],
"updated_at": null,
"deleted_at": null,
"state": "PENDING",
"created_at": "2016-10-18T09:52:05Z",
"parameters": {}
},
"watcher_object.version": "1.0",
"watcher_object.name": "TerseAuditPayload",
"watcher_object.namespace": "watcher"
},
"global_efficacy": {},
"updated_at": null,
"deleted_at": null,
"strategy_uuid": "cb3d0b58-4415-4d90-b75b-1e96878730e3",
"strategy": {
"watcher_object.data": {
"uuid": "cb3d0b58-4415-4d90-b75b-1e96878730e3",
"created_at": "2016-10-18T09:52:05Z",
"name": "TEST",
"display_name": "test strategy",
"deleted_at": null,
"updated_at": null,
"parameters_spec": {}
},
"watcher_object.version": "1.0",
"watcher_object.name": "StrategyPayload",
"watcher_object.namespace": "watcher"
},
"state": "DELETED"
},
"watcher_object.version": "1.0",
"watcher_object.name": "ActionPlanDeletePayload",
"watcher_object.namespace": "watcher"
},
"event_type": "action_plan.delete",
"message_id": "3d137686-a1fd-4683-ab40-c4210aac2140",
"priority": "INFO"
}

View File

@@ -0,0 +1,55 @@
{
"event_type": "action_plan.execution.end",
"payload": {
"watcher_object.namespace": "watcher",
"watcher_object.name": "ActionPlanActionPayload",
"watcher_object.version": "1.0",
"watcher_object.data": {
"created_at": "2016-10-18T09:52:05Z",
"deleted_at": null,
"audit_uuid": "10a47dd1-4874-4298-91cf-eff046dbdb8d",
"audit": {
"watcher_object.namespace": "watcher",
"watcher_object.name": "TerseAuditPayload",
"watcher_object.version": "1.0",
"watcher_object.data": {
"created_at": "2016-10-18T09:52:05Z",
"deleted_at": null,
"uuid": "10a47dd1-4874-4298-91cf-eff046dbdb8d",
"goal_uuid": "bc830f84-8ae3-4fc6-8bc6-e3dd15e8b49a",
"strategy_uuid": "75234dfe-87e3-4f11-a0e0-3c3305d86a39",
"scope": [],
"audit_type": "ONESHOT",
"state": "SUCCEEDED",
"parameters": {},
"interval": null,
"updated_at": null
}
},
"uuid": "76be87bd-3422-43f9-93a0-e85a577e3061",
"fault": null,
"state": "ONGOING",
"global_efficacy": {},
"strategy_uuid": "cb3d0b58-4415-4d90-b75b-1e96878730e3",
"strategy": {
"watcher_object.namespace": "watcher",
"watcher_object.name": "StrategyPayload",
"watcher_object.version": "1.0",
"watcher_object.data": {
"created_at": "2016-10-18T09:52:05Z",
"deleted_at": null,
"name": "TEST",
"uuid": "cb3d0b58-4415-4d90-b75b-1e96878730e3",
"parameters_spec": {},
"display_name": "test strategy",
"updated_at": null
}
},
"updated_at": null
}
},
"priority": "INFO",
"message_id": "3984dc2b-8aef-462b-a220-8ae04237a56e",
"timestamp": "2016-10-18 09:52:05.219414",
"publisher_id": "infra-optim:node0"
}

View File

@@ -0,0 +1,65 @@
{
"event_type": "action_plan.execution.error",
"publisher_id": "infra-optim:node0",
"priority": "ERROR",
"message_id": "9a45c5ae-0e21-4300-8fa0-5555d52a66d9",
"payload": {
"watcher_object.version": "1.0",
"watcher_object.namespace": "watcher",
"watcher_object.name": "ActionPlanActionPayload",
"watcher_object.data": {
"fault": {
"watcher_object.version": "1.0",
"watcher_object.namespace": "watcher",
"watcher_object.name": "ExceptionPayload",
"watcher_object.data": {
"exception_message": "TEST",
"module_name": "watcher.tests.notifications.test_action_plan_notification",
"function_name": "test_send_action_plan_action_with_error",
"exception": "WatcherException"
}
},
"uuid": "76be87bd-3422-43f9-93a0-e85a577e3061",
"created_at": "2016-10-18T09:52:05Z",
"strategy_uuid": "cb3d0b58-4415-4d90-b75b-1e96878730e3",
"strategy": {
"watcher_object.version": "1.0",
"watcher_object.namespace": "watcher",
"watcher_object.name": "StrategyPayload",
"watcher_object.data": {
"uuid": "cb3d0b58-4415-4d90-b75b-1e96878730e3",
"created_at": "2016-10-18T09:52:05Z",
"name": "TEST",
"updated_at": null,
"display_name": "test strategy",
"parameters_spec": {},
"deleted_at": null
}
},
"updated_at": null,
"deleted_at": null,
"audit_uuid": "10a47dd1-4874-4298-91cf-eff046dbdb8d",
"audit": {
"watcher_object.version": "1.0",
"watcher_object.namespace": "watcher",
"watcher_object.name": "TerseAuditPayload",
"watcher_object.data": {
"parameters": {},
"uuid": "10a47dd1-4874-4298-91cf-eff046dbdb8d",
"goal_uuid": "bc830f84-8ae3-4fc6-8bc6-e3dd15e8b49a",
"strategy_uuid": "75234dfe-87e3-4f11-a0e0-3c3305d86a39",
"created_at": "2016-10-18T09:52:05Z",
"scope": [],
"updated_at": null,
"audit_type": "ONESHOT",
"interval": null,
"deleted_at": null,
"state": "PENDING"
}
},
"global_efficacy": {},
"state": "ONGOING"
}
},
"timestamp": "2016-10-18 09:52:05.219414"
}

View File

@@ -0,0 +1,55 @@
{
"event_type": "action_plan.execution.start",
"payload": {
"watcher_object.namespace": "watcher",
"watcher_object.name": "ActionPlanActionPayload",
"watcher_object.version": "1.0",
"watcher_object.data": {
"created_at": "2016-10-18T09:52:05Z",
"deleted_at": null,
"audit_uuid": "10a47dd1-4874-4298-91cf-eff046dbdb8d",
"audit": {
"watcher_object.namespace": "watcher",
"watcher_object.name": "TerseAuditPayload",
"watcher_object.version": "1.0",
"watcher_object.data": {
"created_at": "2016-10-18T09:52:05Z",
"deleted_at": null,
"uuid": "10a47dd1-4874-4298-91cf-eff046dbdb8d",
"goal_uuid": "bc830f84-8ae3-4fc6-8bc6-e3dd15e8b49a",
"strategy_uuid": "75234dfe-87e3-4f11-a0e0-3c3305d86a39",
"scope": [],
"audit_type": "ONESHOT",
"state": "PENDING",
"parameters": {},
"interval": null,
"updated_at": null
}
},
"uuid": "76be87bd-3422-43f9-93a0-e85a577e3061",
"fault": null,
"state": "ONGOING",
"global_efficacy": {},
"strategy_uuid": "cb3d0b58-4415-4d90-b75b-1e96878730e3",
"strategy": {
"watcher_object.namespace": "watcher",
"watcher_object.name": "StrategyPayload",
"watcher_object.version": "1.0",
"watcher_object.data": {
"created_at": "2016-10-18T09:52:05Z",
"deleted_at": null,
"name": "TEST",
"uuid": "cb3d0b58-4415-4d90-b75b-1e96878730e3",
"parameters_spec": {},
"display_name": "test strategy",
"updated_at": null
}
},
"updated_at": null
}
},
"priority": "INFO",
"message_id": "3984dc2b-8aef-462b-a220-8ae04237a56e",
"timestamp": "2016-10-18 09:52:05.219414",
"publisher_id": "infra-optim:node0"
}

View File

@@ -0,0 +1,63 @@
{
"payload": {
"watcher_object.version": "1.0",
"watcher_object.data": {
"audit_uuid": "10a47dd1-4874-4298-91cf-eff046dbdb8d",
"audit": {
"watcher_object.version": "1.0",
"watcher_object.data": {
"audit_type": "ONESHOT",
"scope": [],
"created_at": "2016-10-18T09:52:05Z",
"uuid": "10a47dd1-4874-4298-91cf-eff046dbdb8d",
"goal_uuid": "bc830f84-8ae3-4fc6-8bc6-e3dd15e8b49a",
"strategy_uuid": "75234dfe-87e3-4f11-a0e0-3c3305d86a39",
"interval": null,
"updated_at": null,
"state": "PENDING",
"deleted_at": null,
"parameters": {}
},
"watcher_object.namespace": "watcher",
"watcher_object.name": "TerseAuditPayload"
},
"created_at": "2016-10-18T09:52:05Z",
"uuid": "76be87bd-3422-43f9-93a0-e85a577e3061",
"updated_at": null,
"state_update": {
"watcher_object.version": "1.0",
"watcher_object.data": {
"old_state": "PENDING",
"state": "ONGOING"
},
"watcher_object.namespace": "watcher",
"watcher_object.name": "ActionPlanStateUpdatePayload"
},
"state": "ONGOING",
"deleted_at": null,
"strategy_uuid": "cb3d0b58-4415-4d90-b75b-1e96878730e3",
"strategy": {
"watcher_object.version": "1.0",
"watcher_object.data": {
"name": "TEST",
"uuid": "cb3d0b58-4415-4d90-b75b-1e96878730e3",
"display_name": "test strategy",
"created_at": "2016-10-18T09:52:05Z",
"updated_at": null,
"deleted_at": null,
"parameters_spec": {}
},
"watcher_object.namespace": "watcher",
"watcher_object.name": "StrategyPayload"
},
"global_efficacy": {}
},
"watcher_object.namespace": "watcher",
"watcher_object.name": "ActionPlanUpdatePayload"
},
"publisher_id": "infra-optim:node0",
"priority": "INFO",
"timestamp": "2016-10-18 09:52:05.219414",
"event_type": "action_plan.update",
"message_id": "0a8a7329-fd5a-4ec6-97d7-2b776ce51a4c"
}

View File

@@ -10,6 +10,7 @@
"state": "PENDING",
"updated_at": null,
"deleted_at": null,
"goal_uuid": "bc830f84-8ae3-4fc6-8bc6-e3dd15e8b49a",
"goal": {
"watcher_object.data": {
"uuid": "bc830f84-8ae3-4fc6-8bc6-e3dd15e8b49a",
@@ -26,6 +27,7 @@
},
"interval": null,
"scope": [],
"strategy_uuid": "75234dfe-87e3-4f11-a0e0-3c3305d86a39",
"strategy": {
"watcher_object.data": {
"parameters_spec": {

View File

@@ -10,6 +10,7 @@
"state": "DELETED",
"updated_at": null,
"deleted_at": null,
"goal_uuid": "bc830f84-8ae3-4fc6-8bc6-e3dd15e8b49a",
"goal": {
"watcher_object.data": {
"uuid": "bc830f84-8ae3-4fc6-8bc6-e3dd15e8b49a",
@@ -26,6 +27,7 @@
},
"interval": null,
"scope": [],
"strategy_uuid": "75234dfe-87e3-4f11-a0e0-3c3305d86a39",
"strategy": {
"watcher_object.data": {
"parameters_spec": {

View File

@@ -11,6 +11,7 @@
"updated_at": null,
"deleted_at": null,
"fault": null,
"goal_uuid": "bc830f84-8ae3-4fc6-8bc6-e3dd15e8b49a",
"goal": {
"watcher_object.data": {
"uuid": "bc830f84-8ae3-4fc6-8bc6-e3dd15e8b49a",
@@ -27,6 +28,7 @@
},
"interval": null,
"scope": [],
"strategy_uuid": "75234dfe-87e3-4f11-a0e0-3c3305d86a39",
"strategy": {
"watcher_object.data": {
"parameters_spec": {

View File

@@ -21,6 +21,7 @@
"watcher_object.namespace": "watcher",
"watcher_object.version": "1.0"
},
"goal_uuid": "bc830f84-8ae3-4fc6-8bc6-e3dd15e8b49a",
"goal": {
"watcher_object.data": {
"uuid": "bc830f84-8ae3-4fc6-8bc6-e3dd15e8b49a",
@@ -37,6 +38,7 @@
},
"interval": null,
"scope": [],
"strategy_uuid": "75234dfe-87e3-4f11-a0e0-3c3305d86a39",
"strategy": {
"watcher_object.data": {
"parameters_spec": {

View File

@@ -11,6 +11,7 @@
"updated_at": null,
"deleted_at": null,
"fault": null,
"goal_uuid": "bc830f84-8ae3-4fc6-8bc6-e3dd15e8b49a",
"goal": {
"watcher_object.data": {
"uuid": "bc830f84-8ae3-4fc6-8bc6-e3dd15e8b49a",
@@ -27,6 +28,7 @@
},
"interval": null,
"scope": [],
"strategy_uuid": "75234dfe-87e3-4f11-a0e0-3c3305d86a39",
"strategy": {
"watcher_object.data": {
"parameters_spec": {

View File

@@ -11,6 +11,7 @@
"updated_at": null,
"deleted_at": null,
"fault": null,
"goal_uuid": "bc830f84-8ae3-4fc6-8bc6-e3dd15e8b49a",
"goal": {
"watcher_object.data": {
"uuid": "bc830f84-8ae3-4fc6-8bc6-e3dd15e8b49a",
@@ -27,6 +28,7 @@
},
"interval": null,
"scope": [],
"strategy_uuid": "75234dfe-87e3-4f11-a0e0-3c3305d86a39",
"strategy": {
"watcher_object.data": {
"parameters_spec": {

View File

@@ -21,6 +21,7 @@
"watcher_object.namespace": "watcher",
"watcher_object.version": "1.0"
},
"goal_uuid": "bc830f84-8ae3-4fc6-8bc6-e3dd15e8b49a",
"goal": {
"watcher_object.data": {
"uuid": "bc830f84-8ae3-4fc6-8bc6-e3dd15e8b49a",
@@ -37,6 +38,7 @@
},
"interval": null,
"scope": [],
"strategy_uuid": "75234dfe-87e3-4f11-a0e0-3c3305d86a39",
"strategy": {
"watcher_object.data": {
"parameters_spec": {

View File

@@ -11,6 +11,7 @@
"updated_at": null,
"deleted_at": null,
"fault": null,
"goal_uuid": "bc830f84-8ae3-4fc6-8bc6-e3dd15e8b49a",
"goal": {
"watcher_object.data": {
"uuid": "bc830f84-8ae3-4fc6-8bc6-e3dd15e8b49a",
@@ -27,6 +28,7 @@
},
"interval": null,
"scope": [],
"strategy_uuid": "75234dfe-87e3-4f11-a0e0-3c3305d86a39",
"strategy": {
"watcher_object.data": {
"parameters_spec": {

View File

@@ -4,6 +4,7 @@
"payload": {
"watcher_object.name": "AuditUpdatePayload",
"watcher_object.data": {
"strategy_uuid": "75234dfe-87e3-4f11-a0e0-3c3305d86a39",
"strategy": {
"watcher_object.name": "StrategyPayload",
"watcher_object.data": {
@@ -36,6 +37,7 @@
"scope": [],
"created_at": "2016-11-04T16:51:21Z",
"uuid": "f1e0d912-afd9-4bf2-91ef-c99cd08cc1ef",
"goal_uuid": "bc830f84-8ae3-4fc6-8bc6-e3dd15e8b49a",
"goal": {
"watcher_object.name": "GoalPayload",
"watcher_object.data": {

View File

@@ -21,7 +21,7 @@ Overview
Below you will find a diagram, showing the main components of Watcher:
.. image:: ./images/architecture.svg
:width: 100%
:width: 110%
.. _components_definition:
@@ -37,13 +37,12 @@ AMQP Bus
The AMQP message bus handles internal asynchronous communications between the
different Watcher components.
.. _cluster_history_db_definition:
.. _cluster_datasource_definition:
Cluster History Database
------------------------
Datasource
----------
This component stores the data related to the
:ref:`Cluster History <cluster_history_definition>`.
This component stores the metrics related to the cluster.
It can potentially rely on any appropriate storage system (InfluxDB, OpenTSDB,
MongoDB,...) but will probably be more performant when using
@@ -51,14 +50,6 @@ MongoDB,...) but will probably be more performant when using
which are optimized for handling time series data, which are arrays of numbers
indexed by time (a datetime or a datetime range).
.. _cluster_model_db_definition:
Cluster Model Database
------------------------
This component stores the data related to the
:ref:`Cluster Data Model <cluster_data_model_definition>`.
.. _archi_watcher_api_definition:
Watcher API
@@ -193,8 +184,8 @@ data:
: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 data stored in the :ref:`Cluster Datasource
<cluster_datasource_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
@@ -316,7 +307,7 @@ 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
**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
@@ -452,6 +443,10 @@ state may be one of the following:
- **CANCELLED** : the :ref:`Action Plan <action_plan_definition>` was in
**RECOMMENDED**, **PENDING** or **ONGOING** state and was cancelled by the
:ref:`Administrator <administrator_definition>`
- **SUPERSEDED** : the :ref:`Action Plan <action_plan_definition>` was in
RECOMMENDED state and was automatically superseded by Watcher, due to an
expiration delay or an update of the
:ref:`Cluster data model <cluster_data_model_definition>`
The following diagram shows the different possible states of an

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

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
@@ -368,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
======================

View File

@@ -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

@@ -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
----------------------------

View File

@@ -30,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.
@@ -71,11 +71,11 @@ 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

View File

@@ -268,5 +268,5 @@ At this point, you can use your new cluster data model plugin in your
# [...]
dummy_collector = self.collector_manager.get_cluster_model_collector(
"dummy") # "dummy" is the name of the entry point we declared earlier
dummy_model = collector.get_latest_cluster_data_model()
dummy_model = dummy_collector.get_latest_cluster_data_model()
# Do some stuff with this model

View File

@@ -60,8 +60,8 @@ Here is an example showing how you can define a new ``NewGoal`` goal plugin:
# import path: thirdparty.new
from watcher._i18n import _
from watcher.decision_engine.goal import base
from watcher.decision_engine.goal.efficacy import specs
from watcher.decision_engine.strategy.strategies import base
class NewGoal(base.Goal):
@@ -79,11 +79,11 @@ Here is an example showing how you can define a new ``NewGoal`` goal plugin:
@classmethod
def get_efficacy_specification(cls):
return specs.UnclassifiedStrategySpecification()
return specs.Unclassified()
As you may have noticed, the :py:meth:`~.Goal.get_efficacy_specification`
method returns an :py:meth:`~.UnclassifiedStrategySpecification` instance which
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

View File

@@ -39,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
@@ -47,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

View File

@@ -245,75 +245,70 @@ 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/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
Read usage metrics using the Watcher Datasource Helper
------------------------------------------------------
Read usage metrics using the Python binding
-------------------------------------------
You can find the information about the Ceilometer Python binding on the
OpenStack `ceilometer client python API documentation
<http://docs.openstack.org/developer/python-ceilometerclient/api.html>`_
To facilitate the process, Watcher provides the ``osc`` attribute to every
strategy which includes clients to major OpenStack services, including
Ceilometer. So to access it within your strategy, you can do the following:
The following code snippet shows how to invoke a Datasource Helper class:
.. code-block:: py
# Within your strategy "execute()"
cclient = self.osc.ceilometer
# TODO: Do something here
from watcher.datasource import ceilometer as ceil
from watcher.datasource import monasca as mon
@property
def ceilometer(self):
if self._ceilometer is None:
self._ceilometer = ceil.CeilometerHelper(osc=self.osc)
return self._ceilometer
@property
def monasca(self):
if self._monasca is None:
self._monasca = mon.MonascaHelper(osc=self.osc)
return self._monasca
Using that you can now query the values for that specific metric:
.. code-block:: py
query = None # e.g. [{'field': 'foo', 'op': 'le', 'value': 34},]
value_cpu = cclient.samples.list(
meter_name='cpu_util',
limit=10, q=query)
Read usage metrics using the Watcher Cluster History Helper
-----------------------------------------------------------
Here below is the abstract ``BaseClusterHistory`` class of the Helper.
.. 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.decision_engine.cluster.history import ceilometer as ceil
query_history = ceil.CeilometerClusterHistory()
Using that you can now query the values for that specific metric:
.. code-block:: py
query_history.statistic_aggregation(resource_id=compute_node.uuid,
meter_name='compute.node.cpu.percent',
period="7200",
aggregate='avg'
)
if self.config.datasource == "ceilometer":
resource_id = "%s_%s" % (node.uuid, node.hostname)
return self.ceilometer.statistic_aggregation(
resource_id=resource_id,
meter_name='compute.node.cpu.percent',
period="7200",
aggregate='avg',
)
elif self.config.datasource == "monasca":
statistics = self.monasca.statistic_aggregation(
meter_name='compute.node.cpu.percent',
dimensions=dict(hostname=node.uuid),
period=7200,
aggregate='avg'
)

View File

@@ -101,12 +101,6 @@ Cluster Data Model (CDM)
.. watcher-term:: watcher.decision_engine.model.collector.base
.. _cluster_history_definition:
Cluster History
===============
.. watcher-term:: watcher.decision_engine.cluster.history.base
.. _controller_node_definition:
@@ -132,7 +126,7 @@ Compute node
============
Please, read `the official OpenStack definition of a Compute Node
<http://docs.openstack.org/openstack-ops/content/compute_nodes.html>`_.
<http://docs.openstack.org/ops-guide/arch-compute-nodes.html>`_.
.. _customer_definition:

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

View File

@@ -9,8 +9,10 @@ FAILED --> DELETED : Administrator removes\nAction Plan
SUCCEEDED --> DELETED : Administrator removes\nAction Plan
ONGOING --> CANCELLED : Administrator cancels\nAction Plan
RECOMMENDED --> CANCELLED : Administrator cancels\nAction Plan
RECOMMENDED --> SUPERSEDED : The Watcher Decision Engine supersedes\nAction Plan
PENDING --> CANCELLED : Administrator cancels\nAction Plan
CANCELLED --> DELETED
SUPERSEDED --> DELETED
DELETED --> [*]
@enduml

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

View File

@@ -60,6 +60,7 @@ table(audits) {
interval : Integer, nullable
parameters : JSONEncodedDict, nullable
scope : JSONEncodedList, nullable
auto_trigger: Boolean
created_at : DateTime
updated_at : DateTime
@@ -73,7 +74,6 @@ table(action_plans) {
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
@@ -91,7 +91,7 @@ table(actions) {
action_type : String[255]
input_parameters : JSONEncodedDict, nullable
state : String[20], nullable
next : String[36], nullable
parents : JSONEncodedList, nullable
created_at : DateTime
updated_at : DateTime

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 58 KiB

View File

@@ -71,6 +71,9 @@ parameter type default Value description
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

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,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

@@ -89,7 +89,7 @@ How to use it ?
.. code-block:: shell
$ openstack optimize audittemplate create \
at1 vm_consolidation --strategy vm_workload_consolidation
at1 server_consolidation --strategy vm_workload_consolidation
$ openstack optimize audit create -a at1

View File

@@ -92,12 +92,22 @@ parameter type default Value description
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": "hardware.cpu.util", "memory.resident": "hardware.memory.used"}
.. |instance_metrics| replace:: {"cpu_util": "compute.node.cpu.percent", "memory.resident": "hardware.memory.used"}
.. |periods| replace:: {"instance": 720, "node": 600}
Efficacy Indicator
------------------

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

@@ -7,7 +7,7 @@ To launch this task with configured Rally you just need to run:
::
rally task start watcher/rally-jobs/watcher.yaml
rally task start watcher/rally-jobs/watcher-watcher.yaml
Structure
---------

View File

@@ -17,7 +17,6 @@
name: "dummy"
strategy:
name: "dummy"
extra: {}
sla:
failure_rate:
max: 0
@@ -29,7 +28,6 @@
name: "dummy"
strategy:
name: "dummy"
extra: {}
runner:
type: "constant"
times: 10
@@ -56,12 +54,10 @@
name: "workload_balancing"
strategy:
name: "workload_stabilization"
extra: {}
- goal:
name: "dummy"
strategy:
name: "dummy"
extra: {}
sla:
failure_rate:
max: 0

View File

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

View File

@@ -1,7 +1,7 @@
---
features:
- Added a generic scoring engine module, which
will standarize interactions with scoring engines
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,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

@@ -2,4 +2,4 @@
features:
- Added a way to return the of available goals depending
on which strategies have been deployed on the node
where the decison engine is running.
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,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,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,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

@@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
#
# watcher documentation build configuration file, created by
# sphinx-quickstart on Fri Jun 3 11:37:52 2016.
#

View File

@@ -5,23 +5,23 @@
apscheduler # MIT License
enum34;python_version=='2.7' or python_version=='2.6' or python_version=='3.3' # BSD
jsonpatch>=1.1 # BSD
keystoneauth1>=2.14.0 # Apache-2.0
keystonemiddleware!=4.5.0,>=4.2.0 # Apache-2.0
lxml>=2.3 # BSD
keystoneauth1>=2.18.0 # Apache-2.0
keystonemiddleware>=4.12.0 # Apache-2.0
lxml!=3.7.0,>=2.3 # BSD
oslo.concurrency>=3.8.0 # Apache-2.0
oslo.cache>=1.5.0 # Apache-2.0
oslo.config!=3.18.0,>=3.14.0 # Apache-2.0
oslo.context>=2.9.0 # Apache-2.0
oslo.db!=4.13.1,!=4.13.2,>=4.11.0 # Apache-2.0
oslo.db>=4.15.0 # Apache-2.0
oslo.i18n>=2.1.0 # Apache-2.0
oslo.log>=3.11.0 # Apache-2.0
oslo.messaging>=5.2.0 # Apache-2.0
oslo.policy>=1.15.0 # Apache-2.0
oslo.messaging>=5.14.0 # Apache-2.0
oslo.policy>=1.17.0 # Apache-2.0
oslo.reports>=0.6.0 # Apache-2.0
oslo.serialization>=1.10.0 # Apache-2.0
oslo.service>=1.10.0 # Apache-2.0
oslo.utils>=3.18.0 # Apache-2.0
oslo.versionedobjects>=1.13.0 # Apache-2.0
oslo.versionedobjects>=1.17.0 # Apache-2.0
PasteDeploy>=1.5.0 # MIT
pbr>=1.8 # Apache-2.0
pecan!=1.0.2,!=1.0.3,!=1.0.4,!=1.2,>=1.0.0 # BSD
@@ -30,13 +30,16 @@ voluptuous>=0.8.9 # BSD License
python-ceilometerclient>=2.5.0 # Apache-2.0
python-cinderclient!=1.7.0,!=1.7.1,>=1.6.0 # Apache-2.0
python-glanceclient>=2.5.0 # Apache-2.0
python-keystoneclient>=3.6.0 # Apache-2.0
python-keystoneclient>=3.8.0 # Apache-2.0
python-monascaclient>=1.1.0 # Apache-2.0
python-neutronclient>=5.1.0 # Apache-2.0
python-novaclient!=2.33.0,>=2.29.0 # Apache-2.0
python-novaclient!=7.0.0,>=6.0.0 # Apache-2.0
python-openstackclient>=3.3.0 # Apache-2.0
six>=1.9.0 # MIT
SQLAlchemy<1.1.0,>=1.0.10 # MIT
stevedore>=1.17.1 # Apache-2.0
taskflow>=1.26.0 # Apache-2.0
taskflow>=2.7.0 # Apache-2.0
WebOb>=1.6.0 # MIT
WSME>=0.8 # MIT
networkx>=1.10 # BSD

View File

@@ -64,6 +64,7 @@ watcher_scoring_engine_containers =
watcher_strategies =
dummy = watcher.decision_engine.strategy.strategies.dummy_strategy:DummyStrategy
dummy_with_scorer = watcher.decision_engine.strategy.strategies.dummy_with_scorer:DummyWithScorer
dummy_with_resize = watcher.decision_engine.strategy.strategies.dummy_with_resize:DummyWithResize
basic = watcher.decision_engine.strategy.strategies.basic_consolidation:BasicConsolidation
outlet_temperature = watcher.decision_engine.strategy.strategies.outlet_temp_control:OutletTempControl
vm_workload_consolidation = watcher.decision_engine.strategy.strategies.vm_workload_consolidation:VMWorkloadConsolidation
@@ -76,12 +77,14 @@ watcher_actions =
nop = watcher.applier.actions.nop:Nop
sleep = watcher.applier.actions.sleep:Sleep
change_nova_service_state = watcher.applier.actions.change_nova_service_state:ChangeNovaServiceState
resize = watcher.applier.actions.resize:Resize
watcher_workflow_engines =
taskflow = watcher.applier.workflow_engine.default:DefaultWorkFlowEngine
watcher_planners =
default = watcher.decision_engine.planner.default:DefaultPlanner
weight = watcher.decision_engine.planner.weight:WeightPlanner
workload_stabilization = watcher.decision_engine.planner.workload_stabilization:WorkloadStabilizationPlanner
watcher_cluster_data_model_collectors =
compute = watcher.decision_engine.model.collector.nova:NovaClusterDataModelCollector

10
tox.ini
View File

@@ -6,9 +6,7 @@ skipsdist = True
[testenv]
usedevelop = True
whitelist_externals = find
install_command =
constraints: pip install -U --force-reinstall -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt} {opts} {packages}
pip install -U {opts} {packages}
install_command = pip install -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt} {opts} {packages}
setenv =
VIRTUAL_ENV={envdir}
deps = -r{toxinidir}/test-requirements.txt
@@ -27,7 +25,9 @@ setenv = PYTHONHASHSEED=0
commands = {posargs}
[testenv:cover]
commands = python setup.py testr --coverage --testr-args='{posargs}'
commands =
python setup.py testr --coverage --testr-args='{posargs}'
coverage report
[testenv:docs]
setenv = PYTHONHASHSEED=0
@@ -38,7 +38,7 @@ commands =
[testenv:debug]
commands = oslo_debug_helper -t watcher/tests {posargs}
[testenv:config]
[testenv:genconfig]
sitepackages = False
commands =
oslo-config-generator --config-file etc/watcher/watcher-config-generator.conf

View File

@@ -1,5 +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

View File

@@ -1,6 +1,7 @@
# -*- encoding: utf-8 -*-
#
# Copyright © 2012 New Dream Network, LLC (DreamHost)
# Copyright (c) 2016 Intel Corp
#
# 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
@@ -17,19 +18,10 @@
"""Access Control Lists (ACL's) control access the API server."""
from oslo_config import cfg
from watcher.api.middleware import auth_token
from watcher import conf
AUTH_OPTS = [
cfg.BoolOpt('enable_authentication',
default=True,
help='This option enables or disables user authentication '
'via keystone. Default value is True.'),
]
CONF = cfg.CONF
CONF.register_opts(AUTH_OPTS)
CONF = conf.CONF
def install(app, conf, public_routes):
@@ -42,7 +34,7 @@ def install(app, conf, public_routes):
:return: The same WSGI application with ACL installed.
"""
if not cfg.CONF.get('enable_authentication'):
if not CONF.get('enable_authentication'):
return app
return auth_token.AuthTokenMiddleware(app,
conf=dict(conf),

View File

@@ -2,6 +2,7 @@
# Copyright © 2012 New Dream Network, LLC (DreamHost)
# All Rights Reserved.
# Copyright (c) 2016 Intel Corp
#
# 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
@@ -16,49 +17,14 @@
# under the License.
from oslo_config import cfg
import pecan
from watcher._i18n import _
from watcher.api import acl
from watcher.api import config as api_config
from watcher.api import middleware
from watcher import conf
# Register options for the service
API_SERVICE_OPTS = [
cfg.PortOpt('port',
default=9322,
help=_('The port for the watcher API server')),
cfg.StrOpt('host',
default='127.0.0.1',
help=_('The listen IP for the watcher API server')),
cfg.IntOpt('max_limit',
default=1000,
help=_('The maximum number of items returned in a single '
'response from a collection resource')),
cfg.IntOpt('workers',
min=1,
help=_('Number of workers for Watcher API service. '
'The default is equal to the number of CPUs available '
'if that can be determined, else a default worker '
'count of 1 is returned.')),
cfg.BoolOpt('enable_ssl_api',
default=False,
help=_("Enable the integrated stand-alone API to service "
"requests via HTTPS instead of HTTP. If there is a "
"front-end service performing HTTPS offloading from "
"the service, this option should be False; note, you "
"will want to change public API endpoint to represent "
"SSL termination URL with 'public_endpoint' option.")),
]
CONF = cfg.CONF
opt_group = cfg.OptGroup(name='api',
title='Options for the watcher-api service')
CONF.register_group(opt_group)
CONF.register_opts(API_SERVICE_OPTS, opt_group)
CONF = conf.CONF
def get_pecan_config():

View File

@@ -41,7 +41,7 @@ be one of the following:
processed by the :ref:`Watcher Applier <watcher_applier_definition>`
- **SUCCEEDED** : the :ref:`Action <action_definition>` has been executed
successfully
- **FAILED** : an error occured while trying to execute the
- **FAILED** : an error occurred while trying to execute the
:ref:`Action <action_definition>`
- **DELETED** : the :ref:`Action <action_definition>` is still stored in the
:ref:`Watcher database <watcher_database_definition>` but is not returned
@@ -88,7 +88,6 @@ class Action(base.APIBase):
between the internal object model and the API representation of a action.
"""
_action_plan_uuid = None
_next_uuid = None
def _get_action_plan_uuid(self):
return self._action_plan_uuid
@@ -105,22 +104,6 @@ class Action(base.APIBase):
except exception.ActionPlanNotFound:
self._action_plan_uuid = None
def _get_next_uuid(self):
return self._next_uuid
def _set_next_uuid(self, value):
if value == wtypes.Unset:
self._next_uuid = wtypes.Unset
elif value and self._next_uuid != value:
try:
action_next = objects.Action.get(
pecan.request.context, value)
self._next_uuid = action_next.uuid
self.next = action_next.id
except exception.ActionNotFound:
self.action_next_uuid = None
# raise e
uuid = wtypes.wsattr(types.uuid, readonly=True)
"""Unique UUID for this action"""
@@ -138,10 +121,8 @@ class Action(base.APIBase):
input_parameters = types.jsontype
"""One or more key/value pairs """
next_uuid = wsme.wsproperty(types.uuid, _get_next_uuid,
_set_next_uuid,
mandatory=True)
"""This next action UUID"""
parents = wtypes.wsattr(types.jsontype, readonly=True)
"""UUIDs of parent actions"""
links = wsme.wsattr([link.Link], readonly=True)
"""A list containing a self link and associated action links"""
@@ -152,7 +133,6 @@ class Action(base.APIBase):
self.fields = []
fields = list(objects.Action.fields)
fields.append('action_plan_uuid')
fields.append('next_uuid')
for field in fields:
# Skip fields we do not expose.
if not hasattr(self, field):
@@ -163,15 +143,13 @@ class Action(base.APIBase):
self.fields.append('action_plan_id')
setattr(self, 'action_plan_uuid', kwargs.get('action_plan_id',
wtypes.Unset))
setattr(self, 'next_uuid', kwargs.get('next',
wtypes.Unset))
@staticmethod
def _convert_with_links(action, url, expand=True):
if not expand:
action.unset_fields_except(['uuid', 'state', 'next', 'next_uuid',
'action_plan_uuid', 'action_plan_id',
'action_type'])
action.unset_fields_except(['uuid', 'state', 'action_plan_uuid',
'action_plan_id', 'action_type',
'parents'])
action.links = [link.Link.make_link('self', url,
'actions', action.uuid),
@@ -193,9 +171,9 @@ class Action(base.APIBase):
state='PENDING',
created_at=datetime.datetime.utcnow(),
deleted_at=None,
updated_at=datetime.datetime.utcnow())
updated_at=datetime.datetime.utcnow(),
parents=[])
sample._action_plan_uuid = '7ae81bb3-dec3-4289-8d6c-da80bd8001ae'
sample._next_uuid = '7ae81bb3-dec3-4289-8d6c-da80bd8001ae'
return cls._convert_with_links(sample, 'http://localhost:9322', expand)
@@ -216,17 +194,6 @@ class ActionCollection(collection.Collection):
collection.actions = [Action.convert_with_links(p, expand)
for p in actions]
if 'sort_key' in kwargs:
reverse = False
if kwargs['sort_key'] == 'next_uuid':
if 'sort_dir' in kwargs:
reverse = True if kwargs['sort_dir'] == 'desc' else False
collection.actions = sorted(
collection.actions,
key=lambda action: action.next_uuid or '',
reverse=reverse)
collection.next = collection.get_next(limit, url=url, **kwargs)
return collection
@classmethod
@@ -268,10 +235,7 @@ class ActionsController(rest.RestController):
if audit_uuid:
filters['audit_uuid'] = audit_uuid
if sort_key == 'next_uuid':
sort_db_key = None
else:
sort_db_key = sort_key
sort_db_key = sort_key
actions = objects.Action.list(pecan.request.context,
limit,

View File

@@ -106,7 +106,7 @@ class ActionPlanPatchType(types.JsonPatchType):
@staticmethod
def mandatory_attrs():
return ["audit_id", "state", "first_action_id"]
return ["audit_id", "state"]
class ActionPlan(base.APIBase):
@@ -120,7 +120,6 @@ class ActionPlan(base.APIBase):
_audit_uuid = None
_strategy_uuid = None
_strategy_name = None
_first_action_uuid = None
_efficacy_indicators = None
def _get_audit_uuid(self):
@@ -137,21 +136,6 @@ class ActionPlan(base.APIBase):
except exception.AuditNotFound:
self._audit_uuid = None
def _get_first_action_uuid(self):
return self._first_action_uuid
def _set_first_action_uuid(self, value):
if value == wtypes.Unset:
self._first_action_uuid = wtypes.Unset
elif value and self._first_action_uuid != value:
try:
first_action = objects.Action.get(pecan.request.context,
value)
self._first_action_uuid = first_action.uuid
self.first_action_id = first_action.id
except exception.ActionNotFound:
self._first_action_uuid = None
def _get_efficacy_indicators(self):
if self._efficacy_indicators is None:
self._set_efficacy_indicators(wtypes.Unset)
@@ -220,11 +204,6 @@ class ActionPlan(base.APIBase):
uuid = wtypes.wsattr(types.uuid, readonly=True)
"""Unique UUID for this action plan"""
first_action_uuid = wsme.wsproperty(
types.uuid, _get_first_action_uuid, _set_first_action_uuid,
mandatory=True)
"""The UUID of the first action this action plans links to"""
audit_uuid = wsme.wsproperty(types.uuid, _get_audit_uuid, _set_audit_uuid,
mandatory=True)
"""The UUID of the audit this port belongs to"""
@@ -263,7 +242,6 @@ class ActionPlan(base.APIBase):
setattr(self, field, kwargs.get(field, wtypes.Unset))
self.fields.append('audit_uuid')
self.fields.append('first_action_uuid')
self.fields.append('efficacy_indicators')
setattr(self, 'audit_uuid', kwargs.get('audit_id', wtypes.Unset))
@@ -271,16 +249,13 @@ class ActionPlan(base.APIBase):
setattr(self, 'strategy_uuid', kwargs.get('strategy_id', wtypes.Unset))
fields.append('strategy_name')
setattr(self, 'strategy_name', kwargs.get('strategy_id', wtypes.Unset))
setattr(self, 'first_action_uuid',
kwargs.get('first_action_id', wtypes.Unset))
@staticmethod
def _convert_with_links(action_plan, url, expand=True):
if not expand:
action_plan.unset_fields_except(
['uuid', 'state', 'efficacy_indicators', 'global_efficacy',
'updated_at', 'audit_uuid', 'strategy_uuid', 'strategy_name',
'first_action_uuid'])
'updated_at', 'audit_uuid', 'strategy_uuid', 'strategy_name'])
action_plan.links = [
link.Link.make_link(
@@ -305,7 +280,6 @@ class ActionPlan(base.APIBase):
created_at=datetime.datetime.utcnow(),
deleted_at=None,
updated_at=datetime.datetime.utcnow())
sample._first_action_uuid = '57eaf9ab-5aaa-4f7e-bdf7-9a140ac7a720'
sample._audit_uuid = 'abcee106-14d3-4515-b744-5a26885cf6f6'
sample._efficacy_indicators = [{'description': 'Test indicator',
'name': 'test_indicator',
@@ -481,7 +455,8 @@ class ActionPlansController(rest.RestController):
:param action_plan_uuid: UUID of a action.
"""
context = pecan.request.context
action_plan = api_utils.get_resource('ActionPlan', action_plan_uuid)
action_plan = api_utils.get_resource(
'ActionPlan', action_plan_uuid, eager=True)
policy.enforce(context, 'action_plan:delete', action_plan,
action='action_plan:delete')
@@ -496,13 +471,12 @@ class ActionPlansController(rest.RestController):
:param action_plan_uuid: UUID of a action plan.
:param patch: a json PATCH document to apply to this action plan.
"""
launch_action_plan = True
if self.from_actionsPlans:
raise exception.OperationNotPermitted
context = pecan.request.context
action_plan_to_update = api_utils.get_resource('ActionPlan',
action_plan_uuid)
action_plan_to_update = api_utils.get_resource(
'ActionPlan', action_plan_uuid, eager=True)
policy.enforce(context, 'action_plan:update', action_plan_to_update,
action='action_plan:update')

View File

@@ -69,6 +69,8 @@ class AuditPostType(wtypes.Base):
scope = wtypes.wsattr(types.jsontype, readonly=True)
auto_trigger = wtypes.wsattr(bool, mandatory=False)
def as_audit(self, context):
audit_type_values = [val.value for val in objects.audit.AuditType]
if self.audit_type not in audit_type_values:
@@ -115,7 +117,8 @@ class AuditPostType(wtypes.Base):
goal_id=self.goal,
strategy_id=self.strategy,
interval=self.interval,
scope=self.scope,)
scope=self.scope,
auto_trigger=self.auto_trigger)
class AuditPatchType(types.JsonPatchType):
@@ -257,6 +260,9 @@ class Audit(base.APIBase):
scope = wsme.wsattr(types.jsontype, mandatory=False)
"""Audit Scope"""
auto_trigger = wsme.wsattr(bool, mandatory=False, default=False)
"""Autoexecute action plan once audit is succeeded"""
def __init__(self, **kwargs):
self.fields = []
fields = list(objects.Audit.fields)
@@ -313,7 +319,8 @@ class Audit(base.APIBase):
deleted_at=None,
updated_at=datetime.datetime.utcnow(),
interval=7200,
scope=[])
scope=[],
auto_trigger=False)
sample.goal_id = '7ae81bb3-dec3-4289-8d6c-da80bd8001ae'
sample.strategy_id = '7ae81bb3-dec3-4289-8d6c-da80bd8001ff'
@@ -525,7 +532,6 @@ class AuditsController(rest.RestController):
pecan.response.location = link.build_url('audits', new_audit.uuid)
# trigger decision-engine to run the audit
if new_audit.audit_type == objects.audit.AuditType.ONESHOT.value:
dc_client = rpcapi.DecisionEngineAPI()
dc_client.trigger_audit(context, new_audit.uuid)

View File

@@ -1,5 +1,3 @@
# coding: utf-8
#
# Copyright 2013 Red Hat, Inc.
# All Rights Reserved.
#

View File

@@ -20,32 +20,47 @@ from oslo_log import log
from watcher.applier.action_plan import base
from watcher.applier import default
from watcher import notifications
from watcher import objects
from watcher.objects import fields
LOG = log.getLogger(__name__)
class DefaultActionPlanHandler(base.BaseActionPlanHandler):
def __init__(self, context, service, action_plan_uuid):
super(DefaultActionPlanHandler, self).__init__()
self.ctx = context
self.service = service
self.action_plan_uuid = action_plan_uuid
def update_action_plan(self, uuid, state):
action_plan = objects.ActionPlan.get_by_uuid(self.ctx, uuid)
action_plan.state = state
action_plan.save()
def execute(self):
try:
self.update_action_plan(self.action_plan_uuid,
objects.action_plan.State.ONGOING)
action_plan = objects.ActionPlan.get_by_uuid(
self.ctx, self.action_plan_uuid, eager=True)
action_plan.state = objects.action_plan.State.ONGOING
action_plan.save()
notifications.action_plan.send_action_notification(
self.ctx, action_plan,
action=fields.NotificationAction.EXECUTION,
phase=fields.NotificationPhase.START)
applier = default.DefaultApplier(self.ctx, self.service)
applier.execute(self.action_plan_uuid)
state = objects.action_plan.State.SUCCEEDED
action_plan.state = objects.action_plan.State.SUCCEEDED
notifications.action_plan.send_action_notification(
self.ctx, action_plan,
action=fields.NotificationAction.EXECUTION,
phase=fields.NotificationPhase.END)
except Exception as e:
LOG.exception(e)
state = objects.action_plan.State.FAILED
action_plan.state = objects.action_plan.State.FAILED
notifications.action_plan.send_action_notification(
self.ctx, action_plan,
action=fields.NotificationAction.EXECUTION,
priority=fields.NotificationPriority.ERROR,
phase=fields.NotificationPhase.ERROR)
finally:
self.update_action_plan(self.action_plan_uuid, state)
action_plan.save()

View File

@@ -0,0 +1,106 @@
# -*- encoding: utf-8 -*-
# Copyright (c) 2017 Servionica
#
# Authors: Alexander Chadin <a.chadin@servionica.ru>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
from oslo_log import log
import six
import voluptuous
from watcher._i18n import _, _LC
from watcher.applier.actions import base
from watcher.common import nova_helper
from watcher.common import utils
LOG = log.getLogger(__name__)
class Resize(base.BaseAction):
"""Resizes a server with specified flavor.
This action will allow you to resize a server to another flavor.
The action schema is::
schema = Schema({
'resource_id': str, # should be a UUID
'flavor': str, # should be either ID or Name of Flavor
})
The `resource_id` is the UUID of the server to resize.
The `flavor` is the ID or Name of Flavor (Nova accepts either ID or Name
of Flavor to resize() function).
"""
# input parameters constants
FLAVOR = 'flavor'
def check_resource_id(self, value):
if (value is not None and
len(value) > 0 and not
utils.is_uuid_like(value)):
raise voluptuous.Invalid(_("The parameter "
"resource_id is invalid."))
@property
def schema(self):
return voluptuous.Schema({
voluptuous.Required(self.RESOURCE_ID): self.check_resource_id,
voluptuous.Required(self.FLAVOR):
voluptuous.All(voluptuous.Any(*six.string_types),
voluptuous.Length(min=1)),
})
@property
def instance_uuid(self):
return self.resource_id
@property
def flavor(self):
return self.input_parameters.get(self.FLAVOR)
def resize(self):
nova = nova_helper.NovaHelper(osc=self.osc)
LOG.debug("Resize instance %s to %s flavor", self.instance_uuid,
self.flavor)
instance = nova.find_instance(self.instance_uuid)
result = None
if instance:
try:
result = nova.resize_instance(
instance_id=self.instance_uuid, flavor=self.flavor)
except Exception as exc:
LOG.exception(exc)
LOG.critical(
_LC("Unexpected error occurred. Resizing failed for "
"instance %s."), self.instance_uuid)
return result
def execute(self):
return self.resize()
def revert(self):
return self.migrate(destination=self.source_node)
def pre_condition(self):
# TODO(jed): check if the instance exists / check if the instance is on
# the source_node
pass
def post_condition(self):
# TODO(jed): check extra parameters (network response, etc.)
pass

View File

@@ -56,7 +56,7 @@ class DefaultApplier(base.BaseApplier):
def execute(self, action_plan_uuid):
LOG.debug("Executing action plan %s ", action_plan_uuid)
filters = {'action_plan_uuid': action_plan_uuid}
actions = objects.Action.list(self.context,
filters=filters)
actions = objects.Action.list(self.context, filters=filters)
return self.engine.execute(actions)

View File

@@ -1,5 +1,6 @@
# -*- encoding: utf-8 -*-
# Copyright (c) 2015 b<>com
# Copyright (c) 2016 Intel Corp
#
# Authors: Jean-Emile DARTOIS <jean-emile.dartois@b-com.com>
#
@@ -17,41 +18,12 @@
# limitations under the License.
#
from oslo_config import cfg
from watcher.applier.messaging import trigger
from watcher.common import service_manager
CONF = cfg.CONF
from watcher import conf
# Register options
APPLIER_MANAGER_OPTS = [
cfg.IntOpt('workers',
default='1',
min=1,
required=True,
help='Number of workers for applier, default value is 1.'),
cfg.StrOpt('conductor_topic',
default='watcher.applier.control',
help='The topic name used for'
'control events, this topic '
'used for rpc call '),
cfg.StrOpt('publisher_id',
default='watcher.applier.api',
help='The identifier used by watcher '
'module on the message broker'),
cfg.StrOpt('workflow_engine',
default='taskflow',
required=True,
help='Select the engine to use to execute the workflow')
]
opt_group = cfg.OptGroup(name='watcher_applier',
title='Options for the Applier messaging'
'core')
CONF.register_group(opt_group)
CONF.register_opts(APPLIER_MANAGER_OPTS, opt_group)
CONF = conf.CONF
class ApplierManager(service_manager.ServiceManager):

View File

@@ -1,5 +1,6 @@
# -*- encoding: utf-8 -*-
# Copyright (c) 2015 b<>com
# Copyright (c) 2016 Intel Corp
#
# Authors: Jean-Emile DARTOIS <jean-emile.dartois@b-com.com>
#
@@ -16,18 +17,14 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from oslo_config import cfg
from watcher.applier import manager
from watcher.common import exception
from watcher.common import service
from watcher.common import service_manager
from watcher.common import utils
from watcher import conf
CONF = cfg.CONF
CONF.register_group(manager.opt_group)
CONF.register_opts(manager.APPLIER_MANAGER_OPTS, manager.opt_group)
CONF = conf.CONF
class ApplierAPI(service.Service):

View File

@@ -15,10 +15,12 @@
# limitations under the License.
#
from oslo_concurrency import processutils
from oslo_config import cfg
from oslo_log import log
from taskflow import engines
from taskflow.patterns import graph_flow as gf
from taskflow import task
from taskflow import task as flow_task
from watcher._i18n import _LE, _LW, _LC
from watcher.applier.workflow_engine import base
@@ -48,6 +50,18 @@ class DefaultWorkFlowEngine(base.BaseWorkFlowEngine):
# (True to allow v execution or False to not).
return True
@classmethod
def get_config_opts(cls):
return [
cfg.IntOpt(
'max_workers',
default=processutils.get_worker_count(),
min=1,
required=True,
help='Number of workers for taskflow engine '
'to execute actions.')
]
def execute(self, actions):
try:
# NOTE(jed) We want to have a strong separation of concern
@@ -56,34 +70,32 @@ class DefaultWorkFlowEngine(base.BaseWorkFlowEngine):
# We want to provide the 'taskflow' engine by
# default although we still want to leave the possibility for
# the users to change it.
# todo(jed) we need to change the way the actions are stored.
# The current implementation only use a linked list of actions.
# The current implementation uses graph with linked actions.
# todo(jed) add olso conf for retry and name
flow = gf.Flow("watcher_flow")
previous = None
actions_uuid = {}
for a in actions:
task = TaskFlowActionContainer(a, self)
flow.add(task)
if previous is None:
previous = task
# we have only one Action in the Action Plan
if len(actions) == 1:
nop = TaskFlowNop()
flow.add(nop)
flow.link(previous, nop)
else:
# decider == guard (UML)
flow.link(previous, task, decider=self.decider)
previous = task
actions_uuid[a.uuid] = task
e = engines.load(flow)
for a in actions:
for parent_id in a.parents:
flow.link(actions_uuid[parent_id], actions_uuid[a.uuid],
decider=self.decider)
e = engines.load(
flow, engine='parallel',
max_workers=self.config.max_workers)
e.run()
return flow
except Exception as e:
raise exception.WorkflowExecutionException(error=e)
class TaskFlowActionContainer(task.Task):
class TaskFlowActionContainer(flow_task.Task):
def __init__(self, db_action, engine):
name = "action_type:{0} uuid:{1}".format(db_action.action_type,
db_action.uuid)
@@ -148,7 +160,7 @@ class TaskFlowActionContainer(task.Task):
LOG.critical(_LC("Oops! We need a disaster recover plan."))
class TaskFlowNop(task.Task):
class TaskFlowNop(flow_task.Task):
"""This class is used in case of the workflow have only one Action.
We need at least two atoms to create a link.

View File

@@ -71,7 +71,7 @@ def add_command_parsers(subparsers):
"Optionally, use --revision to specify an alembic revision "
"string to upgrade to.")
parser.set_defaults(func=DBCommand.upgrade)
parser.add_argument('--revision', nargs='?')
parser.add_argument('revision', nargs='?')
parser = subparsers.add_parser(
'downgrade',
@@ -79,10 +79,10 @@ def add_command_parsers(subparsers):
"While optional, one should generally use --revision to "
"specify the alembic revision string to downgrade to.")
parser.set_defaults(func=DBCommand.downgrade)
parser.add_argument('--revision', nargs='?')
parser.add_argument('revision', nargs='?')
parser = subparsers.add_parser('stamp')
parser.add_argument('--revision', nargs='?')
parser.add_argument('revision', nargs='?')
parser.set_defaults(func=DBCommand.stamp)
parser = subparsers.add_parser(

View File

@@ -15,51 +15,18 @@ from cinderclient import client as ciclient
from glanceclient import client as glclient
from keystoneauth1 import loading as ka_loading
from keystoneclient import client as keyclient
from monascaclient import client as monclient
from neutronclient.neutron import client as netclient
from novaclient import client as nvclient
from oslo_config import cfg
from watcher._i18n import _
from watcher.common import exception
from watcher import conf
NOVA_CLIENT_OPTS = [
cfg.StrOpt('api_version',
default='2',
help=_('Version of Nova API to use in novaclient.'))]
GLANCE_CLIENT_OPTS = [
cfg.StrOpt('api_version',
default='2',
help=_('Version of Glance API to use in glanceclient.'))]
CINDER_CLIENT_OPTS = [
cfg.StrOpt('api_version',
default='2',
help=_('Version of Cinder API to use in cinderclient.'))]
CEILOMETER_CLIENT_OPTS = [
cfg.StrOpt('api_version',
default='2',
help=_('Version of Ceilometer API to use in '
'ceilometerclient.'))]
NEUTRON_CLIENT_OPTS = [
cfg.StrOpt('api_version',
default='2.0',
help=_('Version of Neutron API to use in neutronclient.'))]
cfg.CONF.register_opts(NOVA_CLIENT_OPTS, group='nova_client')
cfg.CONF.register_opts(GLANCE_CLIENT_OPTS, group='glance_client')
cfg.CONF.register_opts(CINDER_CLIENT_OPTS, group='cinder_client')
cfg.CONF.register_opts(CEILOMETER_CLIENT_OPTS, group='ceilometer_client')
cfg.CONF.register_opts(NEUTRON_CLIENT_OPTS, group='neutron_client')
CONF = conf.CONF
_CLIENTS_AUTH_GROUP = 'watcher_clients_auth'
ka_loading.register_auth_conf_options(cfg.CONF, _CLIENTS_AUTH_GROUP)
ka_loading.register_session_conf_options(cfg.CONF, _CLIENTS_AUTH_GROUP)
class OpenStackClients(object):
"""Convenience class to create and cache client instances."""
@@ -74,12 +41,13 @@ class OpenStackClients(object):
self._glance = None
self._cinder = None
self._ceilometer = None
self._monasca = None
self._neutron = None
def _get_keystone_session(self):
auth = ka_loading.load_auth_from_conf_options(cfg.CONF,
auth = ka_loading.load_auth_from_conf_options(CONF,
_CLIENTS_AUTH_GROUP)
sess = ka_loading.load_session_from_conf_options(cfg.CONF,
sess = ka_loading.load_session_from_conf_options(CONF,
_CLIENTS_AUTH_GROUP,
auth=auth)
return sess
@@ -95,7 +63,7 @@ class OpenStackClients(object):
return self._session
def _get_client_option(self, client, option):
return getattr(getattr(cfg.CONF, '%s_client' % client), option)
return getattr(getattr(CONF, '%s_client' % client), option)
@exception.wrap_keystone_exception
def keystone(self):
@@ -145,6 +113,35 @@ class OpenStackClients(object):
session=self.session)
return self._ceilometer
@exception.wrap_keystone_exception
def monasca(self):
if self._monasca:
return self._monasca
monascaclient_version = self._get_client_option(
'monasca', 'api_version')
token = self.session.get_token()
watcher_clients_auth_config = CONF.get(_CLIENTS_AUTH_GROUP)
service_type = 'monitoring'
monasca_kwargs = {
'auth_url': watcher_clients_auth_config.auth_url,
'cert_file': watcher_clients_auth_config.certfile,
'insecure': watcher_clients_auth_config.insecure,
'key_file': watcher_clients_auth_config.keyfile,
'keystone_timeout': watcher_clients_auth_config.timeout,
'os_cacert': watcher_clients_auth_config.cafile,
'service_type': service_type,
'token': token,
'username': watcher_clients_auth_config.username,
'password': watcher_clients_auth_config.password,
}
endpoint = self.session.get_endpoint(service_type=service_type)
self._monasca = monclient.Client(
monascaclient_version, endpoint, **monasca_kwargs)
return self._monasca
@exception.wrap_keystone_exception
def neutron(self):
if self._neutron:

View File

@@ -75,7 +75,7 @@ class RequestContext(context.RequestContext):
self.domain_name = domain_name
self.domain_id = domain_id
self.auth_token_info = auth_token_info
self.user_id = user_id
self.user_id = user_id or user
self.project_id = project_id
if not timestamp:
timestamp = timeutils.utcnow()

View File

@@ -26,22 +26,16 @@ import functools
import sys
from keystoneclient import exceptions as keystone_exceptions
from oslo_config import cfg
from oslo_log import log as logging
import six
from watcher._i18n import _, _LE
from watcher import conf
LOG = logging.getLogger(__name__)
EXC_LOG_OPTS = [
cfg.BoolOpt('fatal_exception_format_errors',
default=False,
help='Make exception message format errors fatal.'),
]
CONF = cfg.CONF
CONF.register_opts(EXC_LOG_OPTS)
CONF = conf.CONF
def wrap_keystone_exception(func):
@@ -180,6 +174,14 @@ class EagerlyLoadedAuditRequired(InvalidAudit):
msg_fmt = _("Audit %(audit)s was not eagerly loaded")
class InvalidActionPlan(Invalid):
msg_fmt = _("Action plan %(action_plan)s is invalid")
class EagerlyLoadedActionPlanRequired(InvalidActionPlan):
msg_fmt = _("Action plan %(action_plan)s was not eagerly loaded")
class InvalidUUID(Invalid):
msg_fmt = _("Expected a uuid but received %(uuid)s")
@@ -264,6 +266,12 @@ class ActionPlanReferenced(Invalid):
"multiple actions")
class ActionPlanIsOngoing(Conflict):
msg_fmt = _("Action Plan %(action_plan)s is currently running. "
"New Action Plan %(new_action_plan)s will be set as "
"SUPERSEDED")
class ActionNotFound(ResourceNotFound):
msg_fmt = _("Action %(action)s could not be found")
@@ -282,6 +290,10 @@ class ActionFilterCombinationProhibited(Invalid):
"prohibited")
class UnsupportedActionType(UnsupportedError):
msg_fmt = _("Provided %(action_type) is not supported yet")
class EfficacyIndicatorNotFound(ResourceNotFound):
msg_fmt = _("Efficacy indicator %(efficacy_indicator)s could not be found")
@@ -340,6 +352,10 @@ class MetricCollectorNotDefined(WatcherException):
msg_fmt = _("The metrics resource collector is not defined")
class ClusterStateStale(WatcherException):
msg_fmt = _("The cluster state is stale")
class ClusterDataModelCollectionError(WatcherException):
msg_fmt = _("The cluster data model '%(cdm)s' could not be built")
@@ -370,6 +386,11 @@ class NoMetricValuesForInstance(WatcherException):
msg_fmt = _("No values returned by %(resource_id)s for %(metric_name)s.")
class UnsupportedDataSource(UnsupportedError):
msg_fmt = _("Datasource %(datasource)s is not supported "
"by strategy %(strategy)s")
class NoSuchMetricForHost(WatcherException):
msg_fmt = _("No %(metric)s metric for %(host)s found.")
@@ -389,11 +410,15 @@ class WildcardCharacterIsUsed(WatcherException):
# Model
class InstanceNotFound(WatcherException):
class ComputeResourceNotFound(WatcherException):
msg_fmt = _("The compute resource '%(name)s' could not be found")
class InstanceNotFound(ComputeResourceNotFound):
msg_fmt = _("The instance '%(name)s' could not be found")
class ComputeNodeNotFound(WatcherException):
class ComputeNodeNotFound(ComputeResourceNotFound):
msg_fmt = _("The compute node %(name)s could not be found")

View File

@@ -23,6 +23,7 @@ import time
from oslo_log import log
import cinderclient.exceptions as ciexceptions
import glanceclient.exc as glexceptions
import novaclient.exceptions as nvexceptions
from watcher.common import clients
@@ -63,6 +64,15 @@ class NovaHelper(object):
LOG.exception(exc)
raise exception.ComputeNodeNotFound(name=node_hostname)
def get_instance_list(self):
return self.nova.servers.list(search_opts={'all_tenants': True})
def get_service(self, service_id):
return self.nova.services.find(id=service_id)
def get_flavor(self, flavor_id):
return self.nova.flavors.get(flavor_id)
def get_aggregate_list(self):
return self.nova.aggregates.list()
@@ -142,7 +152,7 @@ class NovaHelper(object):
# We'll use the same name for the new instance.
imagedict = getattr(instance, "image")
image_id = imagedict["id"]
image = self.nova.images.get(image_id)
image = self.glance.images.get(image_id)
new_image_name = getattr(image, "name")
instance_name = getattr(instance, "name")
@@ -304,6 +314,70 @@ class NovaHelper(object):
return True
def resize_instance(self, instance_id, flavor, retry=120):
"""This method resizes given instance with specified flavor.
This method uses the Nova built-in resize()
action to do a resize of a given instance.
It returns True if the resize was successful,
False otherwise.
:param instance_id: the unique id of the instance to resize.
:param flavor: the name or ID of the flavor to resize to.
"""
LOG.debug("Trying a resize of instance %s to flavor '%s'" % (
instance_id, flavor))
# Looking for the instance to resize
instance = self.find_instance(instance_id)
flavor_id = None
try:
flavor_id = self.nova.flavors.get(flavor)
except nvexceptions.NotFound:
flavor_id = [f.id for f in self.nova.flavors.list() if
f.name == flavor][0]
except nvexceptions.ClientException as e:
LOG.debug("Nova client exception occurred while resizing "
"instance %s. Exception: %s", instance_id, e)
if not flavor_id:
LOG.debug("Flavor not found: %s" % flavor)
return False
if not instance:
LOG.debug("Instance not found: %s" % instance_id)
return False
instance_status = getattr(instance, 'OS-EXT-STS:vm_state')
LOG.debug(
"Instance %s is in '%s' status." % (instance_id,
instance_status))
instance.resize(flavor=flavor_id)
while getattr(instance,
'OS-EXT-STS:vm_state') != 'resized' \
and retry:
instance = self.nova.servers.get(instance.id)
LOG.debug(
'Waiting the resize of {0} to {1}'.format(
instance, flavor_id))
time.sleep(1)
retry -= 1
instance_status = getattr(instance, 'status')
if instance_status != 'VERIFY_RESIZE':
return False
instance.confirm_resize()
LOG.debug("Resizing succeeded : instance %s is now on flavor "
"'%s'.", instance_id, flavor_id)
return True
def live_migrate_instance(self, instance_id, dest_hostname,
block_migration=False, retry=120):
"""This method does a live migration of a given instance
@@ -575,8 +649,8 @@ class NovaHelper(object):
return
try:
image = self.nova.images.get(image_id)
except nvexceptions.NotFound:
image = self.glance.images.get(image_id)
except glexceptions.NotFound:
LOG.debug("Image '%s' not found " % image_id)
return
@@ -644,6 +718,16 @@ class NovaHelper(object):
return network_id
def get_instance_by_uuid(self, instance_uuid):
return [instance for instance in
self.nova.servers.list(search_opts={"all_tenants": True,
"uuid": instance_uuid})]
def get_instance_by_name(self, instance_name):
return [instance for instance in
self.nova.servers.list(search_opts={"all_tenants": True,
"name": instance_name})]
def get_instances_by_node(self, host):
return [instance for instance in
self.nova.servers.list(search_opts={"all_tenants": True})

View File

@@ -14,7 +14,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from watcher.common.messaging.utils import synchronization
from watcher.common import synchronization
class Observable(synchronization.Synchronization):

View File

@@ -17,38 +17,9 @@
import os
from oslo_config import cfg
from watcher import conf
PATH_OPTS = [
cfg.StrOpt('pybasedir',
default=os.path.abspath(os.path.join(os.path.dirname(__file__),
'../')),
help='Directory where the watcher python module is installed.'),
cfg.StrOpt('bindir',
default='$pybasedir/bin',
help='Directory where watcher binaries are installed.'),
cfg.StrOpt('state_path',
default='$pybasedir',
help="Top-level directory for maintaining watcher's state."),
]
CONF = cfg.CONF
CONF.register_opts(PATH_OPTS)
def basedir_def(*args):
"""Return an uninterpolated path relative to $pybasedir."""
return os.path.join('$pybasedir', *args)
def bindir_def(*args):
"""Return an uninterpolated path relative to $bindir."""
return os.path.join('$bindir', *args)
def state_path_def(*args):
"""Return an uninterpolated path relative to $state_path."""
return os.path.join('$state_path', *args)
CONF = conf.CONF
def basedir_rel(*args):

View File

@@ -19,7 +19,6 @@
import re
from jsonschema import validators
from oslo_config import cfg
from oslo_log import log as logging
from oslo_utils import strutils
from oslo_utils import timeutils
@@ -29,18 +28,9 @@ import six
from watcher._i18n import _LW
from watcher.common import exception
from watcher import conf
UTILS_OPTS = [
cfg.StrOpt('rootwrap_config',
default="/etc/watcher/rootwrap.conf",
help='Path to the rootwrap configuration file to use for '
'running commands as root.'),
cfg.StrOpt('tempdir',
help='Explicitly specify the temporary working directory.'),
]
CONF = cfg.CONF
CONF.register_opts(UTILS_OPTS)
CONF = conf.CONF
LOG = logging.getLogger(__name__)

View File

@@ -1,5 +1,6 @@
# -*- encoding: utf-8 -*-
# Copyright (c) 2016 b<>com
# Copyright (c) 2016 Intel Corp
#
# Authors: Vincent FRANCOISE <vincent.francoise@b-com.com>
#
@@ -18,8 +19,38 @@
from oslo_config import cfg
from watcher.conf import api
from watcher.conf import applier
from watcher.conf import ceilometer_client
from watcher.conf import cinder_client
from watcher.conf import clients_auth
from watcher.conf import db
from watcher.conf import decision_engine
from watcher.conf import exception
from watcher.conf import glance_client
from watcher.conf import monasca_client
from watcher.conf import neutron_client
from watcher.conf import nova_client
from watcher.conf import paths
from watcher.conf import planner
from watcher.conf import service
from watcher.conf import utils
CONF = cfg.CONF
service.register_opts(CONF)
api.register_opts(CONF)
utils.register_opts(CONF)
paths.register_opts(CONF)
exception.register_opts(CONF)
db.register_opts(CONF)
planner.register_opts(CONF)
applier.register_opts(CONF)
decision_engine.register_opts(CONF)
monasca_client.register_opts(CONF)
nova_client.register_opts(CONF)
glance_client.register_opts(CONF)
cinder_client.register_opts(CONF)
ceilometer_client.register_opts(CONF)
neutron_client.register_opts(CONF)
clients_auth.register_opts(CONF)

View File

@@ -1,6 +1,7 @@
# -*- encoding: utf-8 -*-
# Copyright 2014
# The Cloudscaling Group, Inc.
# Copyright (c) 2016 Intel Corp
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -17,38 +18,41 @@
from keystoneauth1 import loading as ka_loading
from watcher.api import acl as api_acl
from watcher.api import app as api_app
from watcher.applier import manager as applier_manager
from watcher.common import clients
from watcher.common import exception
from watcher.common import paths
from watcher.db.sqlalchemy import models
from watcher.decision_engine.audit import continuous
from watcher.decision_engine import manager as decision_engine_manager
from watcher.decision_engine.planner import manager as planner_manager
from watcher.conf import api as conf_api
from watcher.conf import applier as conf_applier
from watcher.conf import ceilometer_client as conf_ceilometer_client
from watcher.conf import cinder_client as conf_cinder_client
from watcher.conf import db
from watcher.conf import decision_engine as conf_de
from watcher.conf import exception
from watcher.conf import glance_client as conf_glance_client
from watcher.conf import neutron_client as conf_neutron_client
from watcher.conf import nova_client as conf_nova_client
from watcher.conf import paths
from watcher.conf import planner as conf_planner
from watcher.conf import utils
def list_opts():
"""Legacy aggregation of all the watcher config options"""
return [
('DEFAULT',
(api_app.API_SERVICE_OPTS +
api_acl.AUTH_OPTS +
(conf_api.AUTH_OPTS +
exception.EXC_LOG_OPTS +
paths.PATH_OPTS)),
('api', api_app.API_SERVICE_OPTS),
('database', models.SQL_OPTS),
paths.PATH_OPTS +
utils.UTILS_OPTS)),
('api', conf_api.API_SERVICE_OPTS),
('database', db.SQL_OPTS),
('watcher_planner', conf_planner.WATCHER_PLANNER_OPTS),
('watcher_applier', conf_applier.APPLIER_MANAGER_OPTS),
('watcher_decision_engine',
(decision_engine_manager.WATCHER_DECISION_ENGINE_OPTS +
continuous.WATCHER_CONTINUOUS_OPTS)),
('watcher_applier', applier_manager.APPLIER_MANAGER_OPTS),
('watcher_planner', planner_manager.WATCHER_PLANNER_OPTS),
('nova_client', clients.NOVA_CLIENT_OPTS),
('glance_client', clients.GLANCE_CLIENT_OPTS),
('cinder_client', clients.CINDER_CLIENT_OPTS),
('ceilometer_client', clients.CEILOMETER_CLIENT_OPTS),
('neutron_client', clients.NEUTRON_CLIENT_OPTS),
(conf_de.WATCHER_DECISION_ENGINE_OPTS +
conf_de.WATCHER_CONTINUOUS_OPTS)),
('nova_client', conf_nova_client.NOVA_CLIENT_OPTS),
('glance_client', conf_glance_client.GLANCE_CLIENT_OPTS),
('cinder_client', conf_cinder_client.CINDER_CLIENT_OPTS),
('ceilometer_client', conf_ceilometer_client.CEILOMETER_CLIENT_OPTS),
('neutron_client', conf_neutron_client.NEUTRON_CLIENT_OPTS),
('watcher_clients_auth',
(ka_loading.get_auth_common_conf_options() +
ka_loading.get_auth_plugin_conf_options('password') +

67
watcher/conf/api.py Normal file
View File

@@ -0,0 +1,67 @@
# -*- encoding: utf-8 -*-
# Copyright (c) 2016 Intel Corp
#
# Authors: Prudhvi Rao Shedimbi <prudhvi.rao.shedimbi@intel.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from oslo_config import cfg
api = cfg.OptGroup(name='api',
title='Options for the Watcher API service')
AUTH_OPTS = [
cfg.BoolOpt('enable_authentication',
default=True,
help='This option enables or disables user authentication '
'via keystone. Default value is True.'),
]
API_SERVICE_OPTS = [
cfg.PortOpt('port',
default=9322,
help='The port for the watcher API server'),
cfg.StrOpt('host',
default='127.0.0.1',
help='The listen IP address for the watcher API server'),
cfg.IntOpt('max_limit',
default=1000,
help='The maximum number of items returned in a single '
'response from a collection resource'),
cfg.IntOpt('workers',
min=1,
help='Number of workers for Watcher API service. '
'The default is equal to the number of CPUs available '
'if that can be determined, else a default worker '
'count of 1 is returned.'),
cfg.BoolOpt('enable_ssl_api',
default=False,
help="Enable the integrated stand-alone API to service "
"requests via HTTPS instead of HTTP. If there is a "
"front-end service performing HTTPS offloading from "
"the service, this option should be False; note, you "
"will want to change public API endpoint to represent "
"SSL termination URL with 'public_endpoint' option."),
]
def register_opts(conf):
conf.register_group(api)
conf.register_opts(API_SERVICE_OPTS, group=api)
conf.register_opts(AUTH_OPTS)
def list_opts():
return [('api', API_SERVICE_OPTS), ('DEFAULT', AUTH_OPTS)]

53
watcher/conf/applier.py Normal file
View File

@@ -0,0 +1,53 @@
# -*- encoding: utf-8 -*-
# Copyright (c) 2016 Intel Corp
#
# Authors: Prudhvi Rao Shedimbi <prudhvi.rao.shedimbi@intel.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from oslo_config import cfg
watcher_applier = cfg.OptGroup(name='watcher_applier',
title='Options for the Applier messaging'
'core')
APPLIER_MANAGER_OPTS = [
cfg.IntOpt('workers',
default='1',
min=1,
required=True,
help='Number of workers for applier, default value is 1.'),
cfg.StrOpt('conductor_topic',
default='watcher.applier.control',
help='The topic name used for'
'control events, this topic '
'used for rpc call '),
cfg.StrOpt('publisher_id',
default='watcher.applier.api',
help='The identifier used by watcher '
'module on the message broker'),
cfg.StrOpt('workflow_engine',
default='taskflow',
required=True,
help='Select the engine to use to execute the workflow'),
]
def register_opts(conf):
conf.register_group(watcher_applier)
conf.register_opts(APPLIER_MANAGER_OPTS, group=watcher_applier)
def list_opts():
return [('watcher_applier', APPLIER_MANAGER_OPTS)]

View File

@@ -0,0 +1,37 @@
# -*- encoding: utf-8 -*-
# Copyright (c) 2016 Intel Corp
#
# Authors: Prudhvi Rao Shedimbi <prudhvi.rao.shedimbi@intel.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from oslo_config import cfg
ceilometer_client = cfg.OptGroup(name='ceilometer_client',
title='Configuration Options for Ceilometer')
CEILOMETER_CLIENT_OPTS = [
cfg.StrOpt('api_version',
default='2',
help='Version of Ceilometer API to use in '
'ceilometerclient.')]
def register_opts(conf):
conf.register_group(ceilometer_client)
conf.register_opts(CEILOMETER_CLIENT_OPTS, group=ceilometer_client)
def list_opts():
return [('ceilometer_client', CEILOMETER_CLIENT_OPTS)]

View File

@@ -0,0 +1,36 @@
# -*- encoding: utf-8 -*-
# Copyright (c) 2016 Intel Corp
#
# Authors: Prudhvi Rao Shedimbi <prudhvi.rao.shedimbi@intel.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from oslo_config import cfg
cinder_client = cfg.OptGroup(name='cinder_client',
title='Configuration Options for Cinder')
CINDER_CLIENT_OPTS = [
cfg.StrOpt('api_version',
default='2',
help='Version of Cinder API to use in cinderclient.')]
def register_opts(conf):
conf.register_group(cinder_client)
conf.register_opts(CINDER_CLIENT_OPTS, group=cinder_client)
def list_opts():
return [('cinder_client', CINDER_CLIENT_OPTS)]

View File

@@ -1,7 +1,7 @@
# -*- encoding: utf-8 -*-
# Copyright (c) 2015 b<>com
# Copyright (c) 2016 Intel Corp
#
# Authors: Jean-Emile DARTOIS <jean-emile.dartois@b-com.com>
# Authors: Prudhvi Rao Shedimbi <prudhvi.rao.shedimbi@intel.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -15,19 +15,17 @@
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
from watcher.decision_engine.model import element
from watcher.tests import base
from keystoneauth1 import loading as ka_loading
WATCHER_CLIENTS_AUTH = 'watcher_clients_auth'
class TestDiskInfo(base.TestCase):
def test_all(self):
disk_information = element.DiskInfo()
disk_information.set_size(1024)
self.assertEqual(1024, disk_information.get_size())
def register_opts(conf):
ka_loading.register_session_conf_options(conf, WATCHER_CLIENTS_AUTH)
ka_loading.register_auth_conf_options(conf, WATCHER_CLIENTS_AUTH)
disk_information.set_scheduler = "scheduler_qcq"
disk_information.set_device_name("nom_qcq")
self.assertEqual("nom_qcq", disk_information.get_device_name())
def list_opts():
return [('watcher_clients_auth', ka_loading.get_session_conf_options() +
ka_loading.get_auth_common_conf_options())]

44
watcher/conf/db.py Normal file
View File

@@ -0,0 +1,44 @@
# -*- encoding: utf-8 -*-
# Copyright (c) 2016 Intel Corp
#
# Authors: Prudhvi Rao Shedimbi <prudhvi.rao.shedimbi@intel.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from oslo_config import cfg
from oslo_db import options as oslo_db_options
from watcher.conf import paths
_DEFAULT_SQL_CONNECTION = 'sqlite:///{0}'.format(
paths.state_path_def('watcher.sqlite'))
database = cfg.OptGroup(name='database',
title='Configuration Options for database')
SQL_OPTS = [
cfg.StrOpt('mysql_engine',
default='InnoDB',
help='MySQL engine to use.')
]
def register_opts(conf):
oslo_db_options.set_defaults(conf, connection=_DEFAULT_SQL_CONNECTION)
conf.register_group(database)
conf.register_opts(SQL_OPTS, group=database)
def list_opts():
return [('database', SQL_OPTS)]

View File

@@ -0,0 +1,64 @@
# -*- encoding: utf-8 -*-
# Copyright (c) 2015 Intel Corp
#
# Authors: Prudhvi Rao Shedimbi <prudhvi.rao.shedimbi@intel.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from oslo_config import cfg
watcher_decision_engine = cfg.OptGroup(name='watcher_decision_engine',
title='Defines the parameters of '
'the module decision engine')
WATCHER_DECISION_ENGINE_OPTS = [
cfg.StrOpt('conductor_topic',
default='watcher.decision.control',
help='The topic name used for '
'control events, this topic '
'used for RPC calls'),
cfg.ListOpt('notification_topics',
default=['versioned_notifications', 'watcher_notifications'],
help='The topic names from which notification events '
'will be listened to'),
cfg.StrOpt('publisher_id',
default='watcher.decision.api',
help='The identifier used by the Watcher '
'module on the message broker'),
cfg.IntOpt('max_workers',
default=2,
required=True,
help='The maximum number of threads that can be used to '
'execute strategies'),
]
WATCHER_CONTINUOUS_OPTS = [
cfg.IntOpt('continuous_audit_interval',
default=10,
help='Interval (in seconds) for checking newly created '
'continuous audits.')
]
def register_opts(conf):
conf.register_group(watcher_decision_engine)
conf.register_opts(WATCHER_DECISION_ENGINE_OPTS,
group=watcher_decision_engine)
conf.register_opts(WATCHER_CONTINUOUS_OPTS, group=watcher_decision_engine)
def list_opts():
return [('watcher_decision_engine', WATCHER_DECISION_ENGINE_OPTS),
('watcher_decision_engine', WATCHER_CONTINUOUS_OPTS)]

View File

@@ -1,7 +1,7 @@
# -*- encoding: utf-8 -*-
# Copyright (c) 2015 b<>com
# Copyright (c) 2016 Intel Corp
#
# Authors: Jean-Emile DARTOIS <jean-emile.dartois@b-com.com>
# Authors: Prudhvi Rao Shedimbi <prudhvi.rao.shedimbi@intel.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -15,16 +15,19 @@
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
from watcher.decision_engine.model import element
from watcher.tests import base
from oslo_config import cfg
EXC_LOG_OPTS = [
cfg.BoolOpt('fatal_exception_format_errors',
default=False,
help='Make exception message format errors fatal.'),
]
class TestInstance(base.TestCase):
def register_opts(conf):
conf.register_opts(EXC_LOG_OPTS)
def test_namedelement(self):
instance = element.Instance()
instance.state = element.InstanceState.ACTIVE
self.assertEqual(element.InstanceState.ACTIVE, instance.state)
instance.human_id = "human_05"
self.assertEqual("human_05", instance.human_id)
def list_opts():
return [('DEFAULT', EXC_LOG_OPTS)]

View File

@@ -0,0 +1,36 @@
# -*- encoding: utf-8 -*-
# Copyright (c) 2016 Intel Corp
#
# Authors: Prudhvi Rao Shedimbi <prudhvi.rao.shedimbi@intel.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from oslo_config import cfg
glance_client = cfg.OptGroup(name='glance_client',
title='Configuration Options for Glance')
GLANCE_CLIENT_OPTS = [
cfg.StrOpt('api_version',
default='2',
help='Version of Glance API to use in glanceclient.')]
def register_opts(conf):
conf.register_group(glance_client)
conf.register_opts(GLANCE_CLIENT_OPTS, group=glance_client)
def list_opts():
return [('glance_client', GLANCE_CLIENT_OPTS)]

View File

@@ -0,0 +1,36 @@
# -*- encoding: utf-8 -*-
# Copyright (c) 2016 Intel Corp
#
# Authors: Prudhvi Rao Shedimbi <prudhvi.rao.shedimbi@intel.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from oslo_config import cfg
monasca_client = cfg.OptGroup(name='monasca_client',
title='Configuration Options for Monasca')
MONASCA_CLIENT_OPTS = [
cfg.StrOpt('api_version',
default='2_0',
help='Version of Monasca API to use in monascaclient.')]
def register_opts(conf):
conf.register_group(monasca_client)
conf.register_opts(MONASCA_CLIENT_OPTS, group=monasca_client)
def list_opts():
return [('monasca_client', MONASCA_CLIENT_OPTS)]

View File

@@ -0,0 +1,36 @@
# -*- encoding: utf-8 -*-
# Copyright (c) 2016 Intel Corp
#
# Authors: Prudhvi Rao Shedimbi <prudhvi.rao.shedimbi@intel.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from oslo_config import cfg
neutron_client = cfg.OptGroup(name='neutron_client',
title='Configuration Options for Neutron')
NEUTRON_CLIENT_OPTS = [
cfg.StrOpt('api_version',
default='2.0',
help='Version of Neutron API to use in neutronclient.')]
def register_opts(conf):
conf.register_group(neutron_client)
conf.register_opts(NEUTRON_CLIENT_OPTS, group=neutron_client)
def list_opts():
return [('neutron_client', NEUTRON_CLIENT_OPTS)]

View File

@@ -0,0 +1,36 @@
# -*- encoding: utf-8 -*-
# Copyright (c) 2016 Intel Corp
#
# Authors: Prudhvi Rao Shedimbi <prudhvi.rao.shedimbi@intel.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from oslo_config import cfg
nova_client = cfg.OptGroup(name='nova_client',
title='Configuration Options for Nova')
NOVA_CLIENT_OPTS = [
cfg.StrOpt('api_version',
default='2',
help='Version of Nova API to use in novaclient.')]
def register_opts(conf):
conf.register_group(nova_client)
conf.register_opts(NOVA_CLIENT_OPTS, group=nova_client)
def list_opts():
return [('nova_client', NOVA_CLIENT_OPTS)]

57
watcher/conf/paths.py Normal file
View File

@@ -0,0 +1,57 @@
# -*- encoding: utf-8 -*-
# Copyright (c) 2016 Intel Corp
#
# Authors: Prudhvi Rao Shedimbi <prudhvi.rao.shedimbi@intel.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from oslo_config import cfg
import os
PATH_OPTS = [
cfg.StrOpt('pybasedir',
default=os.path.abspath(os.path.join(os.path.dirname(__file__),
'../')),
help='Directory where the watcher python module is installed.'),
cfg.StrOpt('bindir',
default='$pybasedir/bin',
help='Directory where watcher binaries are installed.'),
cfg.StrOpt('state_path',
default='$pybasedir',
help="Top-level directory for maintaining watcher's state."),
]
def basedir_def(*args):
"""Return an uninterpolated path relative to $pybasedir."""
return os.path.join('$pybasedir', *args)
def bindir_def(*args):
"""Return an uninterpolated path relative to $bindir."""
return os.path.join('$bindir', *args)
def state_path_def(*args):
"""Return an uninterpolated path relative to $state_path."""
return os.path.join('$state_path', *args)
def register_opts(conf):
conf.register_opts(PATH_OPTS)
def list_opts():
return [('DEFAULT', PATH_OPTS)]

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