diff --git a/doc/requirements.txt b/doc/requirements.txt new file mode 100644 index 000000000..966197a1d --- /dev/null +++ b/doc/requirements.txt @@ -0,0 +1,9 @@ +# The order of packages is significant, because pip processes them in the order +# of appearance. Changing the order has an impact on the overall integration +# process, which may cause wedges in the gate later. +openstackdocstheme>=1.20.0 # Apache-2.0 +sphinx>=1.6.5,!=1.6.6,!=1.6.7 # BSD +sphinxcontrib-pecanwsme>=0.8.0 # Apache-2.0 +reno>=2.7.0 # Apache-2.0 +sphinxcontrib-apidoc>=0.2.0 # BSD +os-api-ref>=1.4.0 # Apache-2.0 diff --git a/doc/source/conf.py b/doc/source/conf.py index b0a7c62a8..fda641b64 100755 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -32,7 +32,7 @@ sys.path.insert(0, os.path.abspath('./')) # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = [ 'oslo_config.sphinxext', - 'sphinx.ext.autodoc', + 'sphinxcontrib.apidoc', 'sphinx.ext.viewcode', 'sphinxcontrib.httpdomain', 'sphinxcontrib.pecanwsme.rest', @@ -55,6 +55,18 @@ sample_config_basename = 'watcher' # text edit cycles. # execute "export SPHINX_DEBUG=1" in your terminal to disable +# sphinxcontrib.apidoc options +apidoc_module_dir = '../../watcher' +apidoc_output_dir = 'api' +apidoc_excluded_paths = [ + 'tests/*', + 'db', + 'decision_engine', + 'doc', + 'objects', +] +apidoc_separate_modules = True + # The suffix of source filenames. source_suffix = '.rst' diff --git a/doc/source/index.rst b/doc/source/index.rst index 2805c3eab..19a3f397b 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -117,7 +117,7 @@ Watcher Manual Pages .. toctree:: :hidden: - api/autoindex + api/modules Indices and tables diff --git a/setup.cfg b/setup.cfg index 7239c2293..9b2ee5800 100644 --- a/setup.cfg +++ b/setup.cfg @@ -105,26 +105,6 @@ watcher_cluster_data_model_collectors = baremetal = watcher.decision_engine.model.collector.ironic:BaremetalClusterDataModelCollector -[pbr] -autodoc_index_modules = true -autodoc_exclude_modules = - watcher.db.sqlalchemy.alembic.env - watcher.db.sqlalchemy.alembic.versions.* - watcher.tests.* - watcher.doc - - -[build_sphinx] -source-dir = doc/source -build-dir = doc/build -fresh_env = 1 -all_files = 1 -warning-is-error = 1 - -[upload_sphinx] -upload-dir = doc/build/html - - [compile_catalog] directory = watcher/locale domain = watcher diff --git a/test-requirements.txt b/test-requirements.txt index 3a5c09a4c..8e2b35813 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -12,17 +12,5 @@ os-testr>=1.0.0 # Apache-2.0 testscenarios>=0.5.0 # Apache-2.0/BSD testtools>=2.3.0 # MIT stestr>=2.0.0 # Apache-2.0 - -# Doc requirements -openstackdocstheme>=1.20.0 # Apache-2.0 -sphinx>=1.6.5,!=1.6.6,!=1.6.7 # BSD -sphinxcontrib-pecanwsme>=0.8.0 # Apache-2.0 - -# api-ref os-api-ref>=1.4.0 # Apache-2.0 - -# releasenotes -reno>=2.7.0 # Apache-2.0 - -# bandit bandit>=1.1.0 # Apache-2.0 diff --git a/tox.ini b/tox.ini index 100803dc4..eb0462dad 100644 --- a/tox.ini +++ b/tox.ini @@ -43,13 +43,12 @@ commands = [testenv:docs] basepython = python3 setenv = PYTHONHASHSEED=0 -commands = - doc8 doc/source/ CONTRIBUTING.rst HACKING.rst README.rst - python setup.py build_sphinx +deps = -r{toxinidir}/doc/requirements.txt +commands = sphinx-build -W -b html doc/source doc/build/html [testenv:api-ref] -# This environment is called from CI scripts to test and publish -# the API Ref to developer.openstack.org. +basepython = python3 +deps = -r{toxinidir}/doc/requirements.txt whitelist_externals = bash commands = bash -c 'rm -rf api-ref/build' @@ -93,6 +92,7 @@ ignore-path=doc/source/image_src,doc/source/man,doc/source/api [testenv:releasenotes] basepython = python3 +deps = -r{toxinidir}/doc/requirements.txt commands = sphinx-build -a -W -E -d releasenotes/build/doctrees -b html releasenotes/source releasenotes/build/html [testenv:bandit] diff --git a/watcher/api/app.py b/watcher/api/app.py index 7926eda4a..66e798fcc 100644 --- a/watcher/api/app.py +++ b/watcher/api/app.py @@ -21,7 +21,7 @@ import pecan from watcher.api import acl from watcher.api import config as api_config -from watcher.api import middleware +from watcher.api.middleware import parsable_error from watcher import conf CONF = conf.CONF @@ -42,7 +42,7 @@ def setup_app(config=None): app_conf.pop('root'), logging=getattr(config, 'logging', {}), debug=CONF.debug, - wrap_app=middleware.ParsableErrorMiddleware, + wrap_app=parsable_error.ParsableErrorMiddleware, **app_conf ) diff --git a/watcher/api/middleware/__init__.py b/watcher/api/middleware/__init__.py index 6141cb90d..e69de29bb 100644 --- a/watcher/api/middleware/__init__.py +++ b/watcher/api/middleware/__init__.py @@ -1,25 +0,0 @@ -# -*- encoding: 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 -# -# 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 watcher.api.middleware import auth_token -from watcher.api.middleware import parsable_error - - -ParsableErrorMiddleware = parsable_error.ParsableErrorMiddleware -AuthTokenMiddleware = auth_token.AuthTokenMiddleware - -__all__ = (ParsableErrorMiddleware, - AuthTokenMiddleware) diff --git a/watcher/decision_engine/goal/__init__.py b/watcher/decision_engine/goal/__init__.py index 15a21354b..ec1295c30 100644 --- a/watcher/decision_engine/goal/__init__.py +++ b/watcher/decision_engine/goal/__init__.py @@ -21,7 +21,7 @@ ServerConsolidation = goals.ServerConsolidation ThermalOptimization = goals.ThermalOptimization Unclassified = goals.Unclassified WorkloadBalancing = goals.WorkloadBalancing -NoisyNeighbor = goals.NoisyNeighborOptimization +NoisyNeighborOptimization = goals.NoisyNeighborOptimization SavingEnergy = goals.SavingEnergy HardwareMaintenance = goals.HardwareMaintenance diff --git a/watcher/decision_engine/model/model_root.py b/watcher/decision_engine/model/model_root.py index a72f41d4b..012f2c586 100644 --- a/watcher/decision_engine/model/model_root.py +++ b/watcher/decision_engine/model/model_root.py @@ -87,10 +87,11 @@ class ModelRoot(nx.DiGraph, base.Model): def map_instance(self, instance, node): """Map a newly created instance to a node - :param instance: :py:class:`~.Instance` object or instance UUID - :type instance: str or :py:class:`~.Instance` - :param node: :py:class:`~.ComputeNode` object or node UUID - :type node: str or :py:class:`~.Instance` + :param instance: :py:class:`~.instance.Instance` object or instance + UUID + :type instance: str or :py:class:`~.instance.Instance` + :param node: :py:class:`~.node.ComputeNode` object or node UUID + :type node: str or :py:class:`~.instance.Instance` """ if isinstance(instance, six.string_types): instance = self.get_instance_by_uuid(instance) @@ -309,8 +310,8 @@ class StorageModelRoot(nx.DiGraph, base.Model): def map_pool(self, pool, node): """Map a newly created pool to a node - :param pool: :py:class:`~.Pool` object or pool name - :param node: :py:class:`~.StorageNode` object or node host + :param pool: :py:class:`~.node.Pool` object or pool name + :param node: :py:class:`~.node.StorageNode` object or node host """ if isinstance(pool, six.string_types): pool = self.get_pool_by_pool_name(pool) @@ -325,8 +326,8 @@ class StorageModelRoot(nx.DiGraph, base.Model): def unmap_pool(self, pool, node): """Unmap a pool from a node - :param pool: :py:class:`~.Pool` object or pool name - :param node: :py:class:`~.StorageNode` object or node name + :param pool: :py:class:`~.node.Pool` object or pool name + :param node: :py:class:`~.node.StorageNode` object or node name """ if isinstance(pool, six.string_types): pool = self.get_pool_by_pool_name(pool) @@ -353,8 +354,8 @@ class StorageModelRoot(nx.DiGraph, base.Model): def map_volume(self, volume, pool): """Map a newly created volume to a pool - :param volume: :py:class:`~.Volume` object or volume UUID - :param pool: :py:class:`~.Pool` object or pool name + :param volume: :py:class:`~.volume.Volume` object or volume UUID + :param pool: :py:class:`~.node.Pool` object or pool name """ if isinstance(volume, six.string_types): volume = self.get_volume_by_uuid(volume) @@ -369,8 +370,8 @@ class StorageModelRoot(nx.DiGraph, base.Model): def unmap_volume(self, volume, pool): """Unmap a volume from a pool - :param volume: :py:class:`~.Volume` object or volume UUID - :param pool: :py:class:`~.Pool` object or pool name + :param volume: :py:class:`~.volume.Volume` object or volume UUID + :param pool: :py:class:`~.node.Pool` object or pool name """ if isinstance(volume, six.string_types): volume = self.get_volume_by_uuid(volume) @@ -392,7 +393,7 @@ class StorageModelRoot(nx.DiGraph, base.Model): def get_node_by_name(self, name): """Get a node by node name - :param node: :py:class:`~.StorageNode` object or node name + :param node: :py:class:`~.node.StorageNode` object or node name """ try: return self._get_by_name(name.split("#")[0])