2020-11-19 08:01:15 +00:00
|
|
|
import fileinput
|
2021-02-01 09:53:27 +00:00
|
|
|
import logging
|
2020-11-20 04:55:38 +00:00
|
|
|
import os
|
2020-04-09 13:25:39 +00:00
|
|
|
import shutil
|
2014-03-24 18:23:54 +00:00
|
|
|
import sys
|
2020-11-20 04:55:38 +00:00
|
|
|
import yaml
|
2021-02-12 08:05:06 +00:00
|
|
|
import sphinx.util
|
2020-12-01 06:46:19 +00:00
|
|
|
|
2021-03-28 15:25:02 +00:00
|
|
|
|
2020-12-01 06:46:19 +00:00
|
|
|
top_level = \
|
|
|
|
os.path.dirname(
|
|
|
|
os.path.dirname(
|
|
|
|
os.path.abspath(__file__)))
|
|
|
|
|
|
|
|
|
|
|
|
def parse_ceph_release():
|
|
|
|
with open(os.path.join(top_level, 'src/ceph_release')) as f:
|
|
|
|
lines = f.readlines()
|
|
|
|
assert(len(lines) == 3)
|
|
|
|
# 16, pacific, dev
|
|
|
|
version, codename, status = [line.strip() for line in lines]
|
|
|
|
return version, codename, status
|
|
|
|
|
|
|
|
|
2020-12-01 06:49:56 +00:00
|
|
|
def latest_stable_release():
|
|
|
|
with open(os.path.join(top_level, 'doc/releases/releases.yml')) as input:
|
|
|
|
releases = yaml.safe_load(input)['releases']
|
|
|
|
# get the first release
|
|
|
|
return next(iter(releases.keys()))
|
|
|
|
|
|
|
|
|
2020-12-01 06:56:23 +00:00
|
|
|
def is_release_eol(codename):
|
|
|
|
with open(os.path.join(top_level, 'doc/releases/releases.yml')) as input:
|
|
|
|
releases = yaml.safe_load(input)['releases']
|
|
|
|
return 'actual_eol' in releases.get(codename, {})
|
|
|
|
|
|
|
|
|
2020-11-20 03:46:49 +00:00
|
|
|
# project information
|
2020-11-20 03:03:44 +00:00
|
|
|
project = 'Ceph'
|
2020-11-20 03:28:36 +00:00
|
|
|
copyright = ('2016, Ceph authors and contributors. '
|
|
|
|
'Licensed under Creative Commons Attribution Share Alike 3.0 '
|
|
|
|
'(CC-BY-SA-3.0)')
|
2020-12-01 06:46:19 +00:00
|
|
|
version, codename, release = parse_ceph_release()
|
2020-11-20 03:46:49 +00:00
|
|
|
pygments_style = 'sphinx'
|
|
|
|
|
|
|
|
# HTML output options
|
|
|
|
html_theme = 'ceph'
|
2021-02-13 03:23:23 +00:00
|
|
|
html_theme_options = {
|
|
|
|
'logo_only': True,
|
|
|
|
'display_version': False,
|
|
|
|
'prev_next_buttons_location': 'bottom',
|
|
|
|
'style_external_links': False,
|
|
|
|
'vcs_pageview_mode': '',
|
2021-02-13 04:57:19 +00:00
|
|
|
'style_nav_header_background': '#eee',
|
2021-02-13 03:23:23 +00:00
|
|
|
# Toc options
|
|
|
|
'collapse_navigation': True,
|
|
|
|
'sticky_navigation': True,
|
|
|
|
'navigation_depth': 4,
|
|
|
|
'includehidden': True,
|
|
|
|
'titles_only': False
|
|
|
|
}
|
2020-11-20 03:46:49 +00:00
|
|
|
html_theme_path = ['_themes']
|
|
|
|
html_title = "Ceph Documentation"
|
|
|
|
html_logo = 'logo.png'
|
2020-12-01 06:56:23 +00:00
|
|
|
html_context = {'is_release_eol': is_release_eol(codename)}
|
2020-11-20 03:46:49 +00:00
|
|
|
html_favicon = 'favicon.ico'
|
|
|
|
html_show_sphinx = False
|
|
|
|
html_static_path = ["_static"]
|
|
|
|
html_sidebars = {
|
|
|
|
'**': ['smarttoc.html', 'searchbox.html']
|
|
|
|
}
|
2011-08-19 23:43:21 +00:00
|
|
|
|
2020-11-20 03:46:49 +00:00
|
|
|
html_css_files = ['css/custom.css']
|
|
|
|
|
|
|
|
# general configuration
|
2011-08-19 23:43:21 +00:00
|
|
|
templates_path = ['_templates']
|
|
|
|
source_suffix = '.rst'
|
2020-11-20 03:28:36 +00:00
|
|
|
exclude_patterns = ['**/.#*',
|
|
|
|
'**/*~',
|
|
|
|
'start/quick-common.rst',
|
|
|
|
'**/*.inc.rst']
|
2020-11-20 03:04:43 +00:00
|
|
|
if tags.has('man'): # noqa: F821
|
2017-08-15 18:11:06 +00:00
|
|
|
master_doc = 'man_index'
|
2020-11-20 03:28:36 +00:00
|
|
|
exclude_patterns += ['index.rst',
|
|
|
|
'architecture.rst',
|
|
|
|
'glossary.rst',
|
|
|
|
'release*.rst',
|
2016-05-24 04:53:21 +00:00
|
|
|
'api/*',
|
2020-02-26 10:28:18 +00:00
|
|
|
'cephadm/*',
|
2016-05-24 04:53:21 +00:00
|
|
|
'cephfs/*',
|
|
|
|
'dev/*',
|
2018-06-05 21:18:36 +00:00
|
|
|
'governance.rst',
|
2019-12-02 23:43:26 +00:00
|
|
|
'foundation.rst',
|
2016-05-24 04:53:21 +00:00
|
|
|
'install/*',
|
|
|
|
'mon/*',
|
|
|
|
'rados/*',
|
2017-08-15 18:11:06 +00:00
|
|
|
'mgr/*',
|
2017-08-17 21:02:43 +00:00
|
|
|
'ceph-volume/*',
|
2016-05-24 04:53:21 +00:00
|
|
|
'radosgw/*',
|
|
|
|
'rbd/*',
|
2018-03-07 22:50:28 +00:00
|
|
|
'start/*',
|
|
|
|
'releases/*']
|
2017-08-15 18:42:52 +00:00
|
|
|
else:
|
2020-11-20 03:46:49 +00:00
|
|
|
master_doc = 'index'
|
2017-08-15 18:42:52 +00:00
|
|
|
exclude_patterns += ['man_index.rst']
|
2016-05-24 04:53:21 +00:00
|
|
|
|
2020-11-20 03:46:49 +00:00
|
|
|
build_with_rtd = os.environ.get('READTHEDOCS') == 'True'
|
|
|
|
|
2018-10-01 23:54:19 +00:00
|
|
|
sys.path.insert(0, os.path.abspath('_ext'))
|
|
|
|
|
2011-08-29 22:43:41 +00:00
|
|
|
extensions = [
|
2011-09-30 18:30:28 +00:00
|
|
|
'sphinx.ext.autodoc',
|
2011-09-01 19:42:56 +00:00
|
|
|
'sphinx.ext.graphviz',
|
2020-08-29 16:51:12 +00:00
|
|
|
'sphinx.ext.mathjax',
|
2011-08-29 22:43:41 +00:00
|
|
|
'sphinx.ext.todo',
|
2020-08-28 10:26:26 +00:00
|
|
|
'sphinx-prompt',
|
2020-08-29 16:51:12 +00:00
|
|
|
'sphinx_autodoc_typehints',
|
2020-08-28 10:26:26 +00:00
|
|
|
'sphinx_substitution_extensions',
|
2015-03-17 15:40:00 +00:00
|
|
|
'breathe',
|
2021-01-07 15:43:26 +00:00
|
|
|
'ceph_commands',
|
2018-10-01 23:54:19 +00:00
|
|
|
'ceph_releases',
|
2021-04-14 16:03:10 +00:00
|
|
|
'ceph_confval',
|
2020-09-08 15:06:33 +00:00
|
|
|
'sphinxcontrib.openapi'
|
2011-08-29 22:43:41 +00:00
|
|
|
]
|
2020-04-09 15:14:42 +00:00
|
|
|
|
2020-04-09 13:25:39 +00:00
|
|
|
ditaa = shutil.which("ditaa")
|
|
|
|
if ditaa is not None:
|
|
|
|
extensions += ['sphinxcontrib.ditaa']
|
|
|
|
else:
|
|
|
|
extensions += ['plantweb.directive']
|
|
|
|
plantweb_defaults = {
|
|
|
|
'engine': 'ditaa'
|
|
|
|
}
|
|
|
|
|
2020-04-09 15:14:42 +00:00
|
|
|
if build_with_rtd:
|
|
|
|
extensions += ['sphinx_search.extension']
|
|
|
|
|
2020-11-20 03:46:49 +00:00
|
|
|
# sphinx.ext.todo options
|
2011-08-19 23:43:21 +00:00
|
|
|
todo_include_todos = True
|
|
|
|
|
2020-11-20 03:46:49 +00:00
|
|
|
# sphinx_substitution_extensions options
|
2020-12-01 06:49:56 +00:00
|
|
|
rst_prolog = f"""
|
|
|
|
.. |stable-release| replace:: {latest_stable_release()}
|
2020-08-28 10:26:26 +00:00
|
|
|
"""
|
|
|
|
|
2020-11-20 03:46:49 +00:00
|
|
|
# breath options
|
2015-03-17 15:40:00 +00:00
|
|
|
breathe_default_project = "Ceph"
|
|
|
|
# see $(top_srcdir)/Doxyfile
|
|
|
|
|
|
|
|
breathe_build_directory = os.path.join(top_level, "build-doc")
|
|
|
|
breathe_projects = {"Ceph": os.path.join(top_level, breathe_build_directory)}
|
|
|
|
breathe_projects_source = {
|
|
|
|
"Ceph": (os.path.join(top_level, "src/include/rados"),
|
|
|
|
["rados_types.h", "librados.h"])
|
|
|
|
}
|
2020-11-20 03:28:36 +00:00
|
|
|
breathe_domain_by_extension = {'py': 'py',
|
|
|
|
'c': 'c', 'h': 'c',
|
|
|
|
'cc': 'cxx', 'hpp': 'cxx'}
|
2020-08-28 10:20:13 +00:00
|
|
|
breathe_doxygen_config_options = {
|
|
|
|
'EXPAND_ONLY_PREDEF': 'YES',
|
|
|
|
'MACRO_EXPANSION': 'YES',
|
|
|
|
'PREDEFINED': 'CEPH_RADOS_API= '
|
|
|
|
}
|
2017-11-02 04:19:33 +00:00
|
|
|
|
2020-11-19 08:03:29 +00:00
|
|
|
# graphviz options
|
|
|
|
graphviz_output_format = 'svg'
|
|
|
|
|
2020-11-19 08:01:15 +00:00
|
|
|
def generate_state_diagram(input_paths, output_path):
|
|
|
|
sys.path.append(os.path.join(top_level, 'doc', 'scripts'))
|
|
|
|
from gen_state_diagram import do_filter, StateMachineRenderer
|
|
|
|
inputs = [os.path.join(top_level, fn) for fn in input_paths]
|
|
|
|
output = os.path.join(top_level, output_path)
|
|
|
|
|
|
|
|
def process(app):
|
|
|
|
with fileinput.input(files=inputs) as f:
|
|
|
|
input = do_filter(f)
|
|
|
|
render = StateMachineRenderer()
|
|
|
|
render.read_input(input)
|
|
|
|
with open(output, 'w') as dot_output:
|
|
|
|
render.emit_dot(dot_output)
|
|
|
|
|
|
|
|
return process
|
|
|
|
|
2020-11-20 03:07:47 +00:00
|
|
|
|
2017-11-02 04:19:33 +00:00
|
|
|
# mocking ceph_module offered by ceph-mgr. `ceph_module` is required by
|
|
|
|
# mgr.mgr_module
|
|
|
|
class Dummy(object):
|
|
|
|
def __getattr__(self, _):
|
|
|
|
return lambda *args, **kwargs: None
|
|
|
|
|
2020-11-20 03:07:47 +00:00
|
|
|
|
2017-11-02 04:19:33 +00:00
|
|
|
class Mock(object):
|
|
|
|
__all__ = []
|
2020-11-20 03:07:47 +00:00
|
|
|
|
2017-11-02 04:19:33 +00:00
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def __call__(self, *args, **kwargs):
|
|
|
|
return Mock()
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def __getattr__(cls, name):
|
|
|
|
mock = type(name, (Dummy,), {})
|
|
|
|
mock.__module__ = __name__
|
|
|
|
return mock
|
|
|
|
|
2020-11-20 03:07:47 +00:00
|
|
|
|
2020-11-20 03:46:49 +00:00
|
|
|
# autodoc options
|
2017-11-02 04:19:33 +00:00
|
|
|
sys.modules['ceph_module'] = Mock()
|
|
|
|
|
2020-04-09 15:14:42 +00:00
|
|
|
if build_with_rtd:
|
2020-12-03 10:18:17 +00:00
|
|
|
autodoc_mock_imports = ['ceph']
|
2020-04-09 08:51:06 +00:00
|
|
|
pybinds = ['pybind/mgr',
|
|
|
|
'python-common']
|
|
|
|
else:
|
|
|
|
pybinds = ['pybind',
|
|
|
|
'pybind/mgr',
|
|
|
|
'python-common']
|
|
|
|
|
|
|
|
for c in pybinds:
|
|
|
|
pybind = os.path.join(top_level, 'src', c)
|
2017-11-02 04:19:33 +00:00
|
|
|
if pybind not in sys.path:
|
|
|
|
sys.path.insert(0, pybind)
|
2020-11-20 03:46:49 +00:00
|
|
|
|
2021-02-01 09:53:27 +00:00
|
|
|
# openapi
|
2021-02-12 08:05:06 +00:00
|
|
|
openapi_logger = sphinx.util.logging.getLogger('sphinxcontrib.openapi.openapi30')
|
2021-02-01 09:53:27 +00:00
|
|
|
openapi_logger.setLevel(logging.WARNING)
|
|
|
|
|
2020-11-20 03:46:49 +00:00
|
|
|
|
|
|
|
# handles edit-on-github and old version warning display
|
|
|
|
def setup(app):
|
|
|
|
if ditaa is None:
|
|
|
|
# add "ditaa" as an alias of "diagram"
|
|
|
|
from plantweb.directive import DiagramDirective
|
|
|
|
app.add_directive('ditaa', DiagramDirective)
|
|
|
|
app.connect('builder-inited',
|
|
|
|
generate_state_diagram(['src/osd/PeeringState.h',
|
|
|
|
'src/osd/PeeringState.cc'],
|
|
|
|
'doc/dev/peering_graph.generated.dot'))
|