diff --git a/.github/workflows/automatic-doc-checks.yml b/.github/workflows/automatic-doc-checks.yml index 3c7039b4..712d3b00 100644 --- a/.github/workflows/automatic-doc-checks.yml +++ b/.github/workflows/automatic-doc-checks.yml @@ -1,11 +1,13 @@ -name: Main Documentation Checks +# +name: Automatic doc checks on: push: - branches: [main] + branches: [ main ] pull_request: paths: - - "docs/**" # Only run on changes to the docs directory + - 'docs/**' # Only run on changes to the docs directory + workflow_dispatch: # Manual trigger diff --git a/.github/workflows/check-removed-urls.yml b/.github/workflows/check-removed-urls.yml new file mode 100644 index 00000000..4ee57d37 --- /dev/null +++ b/.github/workflows/check-removed-urls.yml @@ -0,0 +1,56 @@ +name: Check for removed URLs + +on: + workflow_call: + pull_request: + branches: [main] + +jobs: + build-docs: + runs-on: ubuntu-latest + steps: + - name: Checkout PR branch + uses: actions/checkout@v5 + with: + # This implicitly gets the PR branch. Making it explicit causes problems + # with private forks, but it is equivalent to the following: + # repository: ${{ github.event.pull_request.head.repo.full_name }} + # ref: ${{ github.event.pull_request.head.ref }} + fetch-depth: 0 + path: compare + - name: Checkout base branch + uses: actions/checkout@v5 + with: + ref: ${{ github.event.pull_request.base.ref }} + repository: ${{ github.event.pull_request.base.repo.full_name }} + fetch-depth: 0 + path: base + - uses: actions/setup-python@v6 + - name: Build docs + run: | + for dir in compare base; do + pushd ${dir}/docs + make html + popd + done + - name: Generate current URLs list + run: | + for dir in compare base; do + pushd ${dir}/docs + find ./_build/ -name '*.html' \ + | sed 's|/_build||;s|/index.html$|/|;s|.html$||' \ + | sort > urls.txt + popd + done + - name: Compare URLs + run: | + BASE_URLS_PATH="base/docs/urls.txt" + COMPARE_URLS_PATH="compare/docs/urls.txt" + removed=$(comm -23 ${BASE_URLS_PATH} ${COMPARE_URLS_PATH} \ + | grep -v '^\./explanation/security/full-disk-encryption/$' || true) + if [ -n "$removed" ]; then + echo "The following URLs were removed:" + echo "$removed" + echo "Please ensure removed pages are redirected" + exit 1 + fi diff --git a/.github/workflows/cla-check.yml b/.github/workflows/cla-check.yml new file mode 100644 index 00000000..7de30760 --- /dev/null +++ b/.github/workflows/cla-check.yml @@ -0,0 +1,17 @@ +# This workflow checks if the contributor has signed the Canonical Contributor Licence Agreement (CLA) +name: Canonical Contributor Licence Agreement check + +on: + pull_request: + branches: [main] + +permissions: + contents: read + pull-requests: read + +jobs: + cla-check: + runs-on: ubuntu-latest + steps: + - name: Check if CLA signed + uses: canonical/has-signed-canonical-cla@v2 diff --git a/.github/workflows/markdown-style-checks.yml b/.github/workflows/markdown-style-checks.yml index 8247bd51..cb8b5d40 100644 --- a/.github/workflows/markdown-style-checks.yml +++ b/.github/workflows/markdown-style-checks.yml @@ -21,4 +21,4 @@ jobs: fetch-depth: 0 - uses: DavidAnson/markdownlint-cli2-action@b4c9feab76d8025d1e83c653fa3990936df0e6c8 # Commit hash for v16 tag with: - config: "docs/.sphinx/.markdownlint.json" + config: "docs/_dev/.markdownlint.json" diff --git a/.github/workflows/sphinx-python-dependency-build-checks.yml b/.github/workflows/sphinx-python-dependency-build-checks.yml deleted file mode 100644 index 2940d964..00000000 --- a/.github/workflows/sphinx-python-dependency-build-checks.yml +++ /dev/null @@ -1,50 +0,0 @@ -# The purpose of this workflow file is to confirm that the Sphinx -# virtual environment can be built from source, consequently documenting -# the packages required in the build environment to do that. -# -# This is needed because some projects embeds the documentation into built -# artifacts which involves rendering the documentation on the target -# architecture. -# -# Depending on the architecture, pip may or may not have already built wheels -# available, and as such we need to make sure building wheels from source can -# succeed. -name: Sphinx python dependency build checks - -on: - push: - branches: [ main ] - pull_request: - workflow_dispatch: # manual trigger - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - build: - name: build - runs-on: ubuntu-latest - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Install dependencies - run: | - set -ex - sudo apt-get --fix-missing update - sudo apt -y install \ - cargo \ - libpython3-dev \ - libxml2-dev \ - libxslt1-dev \ - make \ - python3-venv \ - rustc \ - libtiff5-dev libjpeg8-dev libopenjp2-7-dev zlib1g-dev libfreetype6-dev liblcms2-dev libwebp-dev tcl8.6-dev tk8.6-dev python3-tk libharfbuzz-dev libfribidi-dev libxcb1-dev - - name: Build Sphinx venv - working-directory: "docs" - run: | - set -ex - make install \ - || ( cat .sphinx/venv/pip_install.log && exit 1 ) diff --git a/docs/.custom_wordlist.txt b/docs/.custom_wordlist.txt index 3a26a5b9..54f776b7 100644 --- a/docs/.custom_wordlist.txt +++ b/docs/.custom_wordlist.txt @@ -147,6 +147,7 @@ Permalink PKI POSIX pre +preboot prometheus radosgw ReadMe @@ -192,6 +193,7 @@ API APIs arounds Auth +AZs auth authorization auto-generated @@ -204,6 +206,7 @@ catalog centralized Centralized ceph +cephadm CephFS CephHealthWarning Cephx @@ -280,9 +283,12 @@ manpage md mds MDS +MDSs mees mentorship MgrReports +MGRs +MONs MiB MicroCeph MicroCeph's @@ -320,6 +326,7 @@ qemu radosgw rbd RBD +reachability readme ReadMe reST @@ -328,6 +335,7 @@ reStructuredText resync rgw RGW +RGWs RO rsyslog RTD @@ -389,10 +397,13 @@ Hyperconverged RadosGW NICs OOB +SSDs SSD SSHing unpartitioned GateWay +Gbps +HDDs Certbot LetsEncrypt utilize diff --git a/docs/.gitignore b/docs/.gitignore index 0f3832ca..0e5048a9 100644 --- a/docs/.gitignore +++ b/docs/.gitignore @@ -1,17 +1,17 @@ # Environment *env*/ -.sphinx/venv/ +.venv/ # Sphinx -.sphinx/warnings.txt -.sphinx/.wordlist.dic -.sphinx/.doctrees/ -.sphinx/update/ -.sphinx/node_modules/ +_dev/warnings.txt +_dev/.wordlist.dic +_dev/.doctrees/ +_dev/update/ +_dev/node_modules/ # Vale -.sphinx/styles/* -.sphinx/vale.ini +_dev/styles/* +_dev/vale.ini # Build outputs _build diff --git a/docs/.sphinx/.wordlist.txt b/docs/.sphinx/.wordlist.txt deleted file mode 100644 index d6f08601..00000000 --- a/docs/.sphinx/.wordlist.txt +++ /dev/null @@ -1,370 +0,0 @@ -ACME -ACME's -addons -AGPLv -API -APIs -balancer -Charmhub -CLI -DCO -Diátaxis -Dqlite -dropdown -EBS -EKS -enablement -favicon -Furo -Git -GitHub -Grafana -IAM -installable -JSON -Juju -Kubeflow -Kubernetes -Launchpad -linter -LTS -LXD -Makefile -Makefiles -Matrix -Mattermost -MicroCeph -MicroCloud -MicroOVN -MyST -namespace -namespaces -NodePort -Numbat -observability -OEM -OLM -Permalink -pre -Quickstart -ReadMe -reST -reStructuredText -roadmap -RTD -subdirectories -subfolders -subtree -TODO -Ubuntu -UI -UUID -VM -webhook -YAML - -AAM -AAR -AArch -ABI -ADB -ADSys -AKS -AMC -AMS -ANAIS -APK -APM -ARMv -ARR -ASIC -AZ -BAU -BOM -BTS -BZR -CAC -CBR -CDK -CDN -CISC -CLA -CMP -CNI -COS -COTS -CPC -CPQ -CPT -CR -CRD -CRI -CSB -CSI -CTR -CVE -DBR -DEP -DHCP -DKMS -DMB -DNS -DPU -DSA -DSE -EE -EFI -EoL -EoS -EPMO -ESM -FCE -FFE -FIPS -FOSS -FPGA -FTBFS -FTI -FUSE -GKE -GPGPU -GPL -GSI -GTM -HA -HAP -HPC -HWE -IC -IHV -IOV -IPMI -IPU -IRCC -iSCSI -ISM -ISR -ISV -ITP -JAAS -KSPP -LTV -MAAS -MDF -MDL -MEC -MLflow -MOTU -MPA -MQL -MRE -MSRP -NATS -NFS -NIC -NIH -NIST -NOC -NOS -NPOASR -NPV -NRE -NUMA -NVIU -NVMe -OBSD -OCI -OCL -OCTO -ODM -OSD -OSS -OVA -OVAL -OVN -OVS -P4 -PCB -PCF -PCKN -PCRE -PKCS -PKS -PMO -POSIX -PPA -PS5 -PXE -RACI -RADOS -RAG -RBAC -RDMA -RTOS -SDK -SDR -SDS -SEG -SFDC -SIP -SKU -SLA -SOW -SQL -SR -SRU -TAM -TCS -TFTP -TLS -TPM -TUI -UCA -UCT -UDS -UIFe -URI -UX -VCS -VNFD -WSL -ZFS - -Anbox -Ansible -Appium -Backports -Ceph -Changelog -Charmcraft -CoC -CoF -Containerd -Coturn -Cryptographic -Devel -Endian -Endianness -Fluentd -GraphQL -HAProxy -HAcluster -Imagecraft -Infiniband -Influxdb -Istio -Kata -Keepalived -KernOS -KernelFactory -Keyring -Keyserver -Kibana -Knative -LXC -Laravel -Libvirt -Linkerd -LinuxONE -Livepatch -Mesos -Metallb -MicroK -MicroStack -Mojo -Multipass -Nagios -NetApp -Netplan -Nginx -OpenSSL -OpenSearch -OpenStack -Openshift -PgBouncer -QEMU -RabbitMQ -Rasterization -Rebase -RegEx -RoM -RoP -RoQA -RoSRM -RoST -Rockcraft -SQLair -Scrcpy -Snapcraft -Snapd -Splunk -Subnet -Superdistro -Superset -Telegraf -Terraform -Testflinger -Thruk -Tigera -TrilioVault -TripleO -Vue -WebRTC -WoU -amd -armhf -autopkgtest -cURL -containeragent -dqlite -dsc -init -jQuery -juju -jujuc -jujud -ppc -riscv -snapcrafting -subcluster -swrast -zSystems -AZs -bcache -cephadm -Clos -colocated -CPUs -customized -Disaggregated -disaggregated -DWPD -Gbps -Gbit -GW -HDDs -Hyperconverged -hyperconverged -Juju's -LACP -lifecycle -MDSs -MGRs -MONs -NICs -NL -OAM -oF -OOB -optimizing -oversubscription -PoC -preboot -RadosGW -reachability -RGWs -SAS -SSD -SSDs -TCO -VMware diff --git a/docs/.sphinx/metrics/build_metrics.sh b/docs/.sphinx/metrics/build_metrics.sh deleted file mode 100755 index bd1ff1cb..00000000 --- a/docs/.sphinx/metrics/build_metrics.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash -# shellcheck disable=all - -links=0 -images=0 - -# count number of links -links=$(find . -type d -path './.sphinx' -prune -o -name '*.html' -exec cat {} + | grep -o "" @echo "-------------------------------------------------------------" @echo -.PHONY: full-help spellcheck-install pa11y-install install run html \ - epub serve clean clean-doc spelling spellcheck linkcheck woke \ - allmetrics pa11y pdf-prep-force pdf-prep pdf vale-install vale \ - update fetch-charm-docs +.PHONY: help full-help html epub pdf linkcheck spelling spellcheck woke \ + vale pa11y run serve install pa11y-install \ + vale-install pdf-prep pdf-prep-force clean clean-doc \ + update lint-md + update fetch-charm-docs -full-help: $(VENVDIR) - @. $(VENV); $(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) +full-help: $(DOCS_VENVDIR) + @. $(DOCS_VENV); $(SPHINX_BUILD) -M help "$(DOCS_SOURCEDIR)" "$(DOCS_BUILDDIR)" $(SPHINX_OPTS) $(O) @echo "\n\033[1;31mNOTE: This help texts shows unsupported targets!\033[0m" @echo "Run 'make help' to see supported targets." # If requirements are updated, venv should be rebuilt and timestamped. -$(VENVDIR): - python3 -c "import venv" || \ - (echo "You must install python3-venv before you can build the documentation."; exit 1) +$(DOCS_VENVDIR): @echo "... setting up virtualenv" - python3 -m venv $(VENVDIR) - . $(VENV); pip install $(PIPOPTS) --require-virtualenv \ + python3 -m venv $(DOCS_VENVDIR) || { echo "You must install python3-venv before you can build the documentation."; exit 1; } + . $(DOCS_VENV); pip install $(PIPOPTS) --require-virtualenv \ --upgrade -r requirements.txt \ - --log $(VENVDIR)/pip_install.log - @test ! -f $(VENVDIR)/pip_list.txt || \ - mv $(VENVDIR)/pip_list.txt $(VENVDIR)/pip_list.txt.bak - @. $(VENV); pip list --local --format=freeze > $(VENVDIR)/pip_list.txt - @touch $(VENVDIR) - -spellcheck-install: - @type aspell >/dev/null 2>&1 || \ - { \ - echo "Installing system-wide \"aspell\" packages..."; \ - confirm_sudo=$(CONFIRM_SUDO); \ - if [ "$$confirm_sudo" != "y" ] && [ "$$confirm_sudo" != "Y" ]; then \ - read -p "This requires sudo privileges. Proceed? [y/N]: " confirm_sudo; \ - fi; \ - if [ "$$confirm_sudo" = "y" ] || [ "$$confirm_sudo" = "Y" ]; then \ - sudo apt-get install aspell aspell-en; \ - else \ - echo "Installation cancelled."; \ - fi \ - } + --log $(DOCS_VENVDIR)/pip_install.log + @test ! -f $(DOCS_VENVDIR)/pip_list.txt || \ + mv $(DOCS_VENVDIR)/pip_list.txt $(DOCS_VENVDIR)/pip_list.txt.bak + @. $(DOCS_VENV); pip list --local --format=freeze > $(DOCS_VENVDIR)/pip_list.txt + @touch $(DOCS_VENVDIR) pa11y-install: - @type $(PA11Y) >/dev/null 2>&1 || { \ + @command -v $(PA11Y_CMD) >/dev/null || { \ echo "Installing \"pa11y\" from npm..."; echo; \ - mkdir -p $(SPHINXDIR)/node_modules/ ; \ - npm install --prefix $(SPHINXDIR) pa11y; \ + mkdir -p $(DEV_DIR)/node_modules/ ; \ + npm install --prefix $(DEV_DIR) pa11y; \ } -install: $(VENVDIR) +pymarkdownlnt-install: install + @. $(DOCS_VENV); test -d $(DOCS_VENVDIR)/lib/python*/site-packages/pymarkdown || pip install pymarkdownlnt==0.9.35 + +install: $(DOCS_VENVDIR) # Fetch charm documentation from the charm-microceph repository. # Set CHARM_REPO_URL and CHARM_BRANCH to override defaults. @@ -101,106 +90,114 @@ fetch-charm-docs: bash $(FETCH_SCRIPT) "$(CHARM_BRANCH)" "$(CHARM_REPO_URL)" run: install fetch-charm-docs - . $(VENV); $(VENVDIR)/bin/sphinx-autobuild -b dirhtml --host $(SPHINX_HOST) --port $(SPHINX_PORT) "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) + . $(DOCS_VENV); $(DOCS_VENVDIR)/bin/sphinx-autobuild -b dirhtml --host $(SPHINX_HOST) --port $(SPHINX_PORT) "$(DOCS_SOURCEDIR)" "$(DOCS_BUILDDIR)" $(SPHINX_OPTS) $(SPHINX_AUTOBUILD_OPTS) -# Doesn't depend on $(BUILDDIR) to rebuild properly at every run. +# Does not depend on $(DOCS_BUILDDIR) to rebuild properly at every run. html: install fetch-charm-docs - . $(VENV); $(SPHINXBUILD) -W --keep-going -b dirhtml "$(SOURCEDIR)" "$(BUILDDIR)" -w $(SPHINXDIR)/warnings.txt $(SPHINXOPTS) + . $(DOCS_VENV); $(SPHINX_BUILD) --fail-on-warning --keep-going -b dirhtml "$(DOCS_SOURCEDIR)" "$(DOCS_BUILDDIR)" -w $(DEV_DIR)/warnings.txt $(SPHINX_OPTS) -epub: install fetch-charm-docs - . $(VENV); $(SPHINXBUILD) -b epub "$(SOURCEDIR)" "$(BUILDDIR)" -w $(SPHINXDIR)/warnings.txt $(SPHINXOPTS) +epub: install + . $(DOCS_VENV); $(SPHINX_BUILD) -b epub "$(DOCS_SOURCEDIR)" "$(DOCS_BUILDDIR)" -w $(DEV_DIR)/warnings.txt $(SPHINX_OPTS) serve: html - cd "$(BUILDDIR)"; python3 -m http.server --bind 127.0.0.1 18000 + cd "$(DOCS_BUILDDIR)"; python3 -m http.server --bind $(SPHINX_HOST) $(SPHINX_PORT) clean: clean-doc - @test ! -e "$(VENVDIR)" -o -d "$(VENVDIR)" -a "$(abspath $(VENVDIR))" != "$(VENVDIR)" - rm -rf $(VENVDIR) - rm -rf $(SPHINXDIR)/node_modules/ - rm -rf $(SPHINXDIR)/styles + @test ! -e "$(DOCS_VENVDIR)" -o -d "$(DOCS_VENVDIR)" -a "$(abspath $(DOCS_VENVDIR))" != "$(DOCS_VENVDIR)" + rm -rf $(DOCS_VENVDIR) + rm -rf $(DEV_DIR)/node_modules/ + rm -rf $(DEV_DIR)/styles rm -rf $(VALE_CONFIG) clean-doc: - git clean -fx "$(BUILDDIR)" - rm -rf $(SPHINXDIR)/.doctrees - -spellcheck: spellcheck-install - . $(VENV) ; python3 -m pyspelling -c $(SPHINXDIR)/spellingcheck.yaml -j $(shell nproc) + git clean -fx "$(DOCS_BUILDDIR)" + rm -rf $(DEV_DIR)/.doctrees -spelling: html spellcheck - -linkcheck: install fetch-charm-docs - . $(VENV) ; $(SPHINXBUILD) -b linkcheck "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) || { grep --color -F "[broken]" "$(BUILDDIR)/output.txt"; exit 1; } +linkcheck: install + . $(DOCS_VENV) ; $(SPHINX_BUILD) -b linkcheck -q "$(DOCS_SOURCEDIR)" "$(DOCS_BUILDDIR)" $(SPHINX_OPTS) || { grep --color -F "[broken]" "$(DOCS_BUILDDIR)/output.txt"; exit 1; } exit 0 pa11y: pa11y-install html - find $(BUILDDIR) -name *.html -print0 | xargs -n 1 -0 $(PA11Y) + find $(DOCS_BUILDDIR) -name *.html -print0 | xargs -n 1 -0 $(PA11Y_CMD) + +# Without --return-code-scheme explicit, pymarkdownlnt returns 1 for multiple scenarios +# By using the explicit scheme, it only returns 1 when no files are found, +# which should not result in failure +lint-md: pymarkdownlnt-install + @. $(DOCS_VENV); pymarkdownlnt \ + --config $(DEV_DIR)/.pymarkdown.json \ + --return-code-scheme explicit \ + scan \ + --recurse \ + --exclude=$(DEV_DIR)/** \ + --exclude=$(DOCS_VENVDIR)/** \ + $(DOCS_SOURCEDIR); \ + status=$$?; \ + if [ $$status -eq 1 ]; then \ + echo "No Markdown files selected for linting"; \ + exit 0; \ + fi; \ + echo "pymarkdownlnt exited with code $$status"; \ + exit $$status; vale-install: install - @. $(VENV); test -d $(SPHINXDIR)/venv/lib/python*/site-packages/vale || pip install rst2html vale - @. $(VENV); test -f $(VALE_CONFIG) || python3 $(SPHINXDIR)/get_vale_conf.py - @echo '.Name=="Canonical.400-Enforce-inclusive-terms"' > $(SPHINXDIR)/styles/woke.filter - @echo '.Level=="error" and .Name!="Canonical.500-Repeated-words" and .Name!="Canonical.000-US-spellcheck"' > $(SPHINXDIR)/styles/error.filter - @echo '.Name=="Canonical.000-US-spellcheck"' > $(SPHINXDIR)/styles/spelling.filter - @. $(VENV); find $(SPHINXDIR)/venv/lib/python*/site-packages/vale/vale_bin -size 195c -exec vale --version \; + @. $(DOCS_VENV); test -f $(VALE_CONFIG) || python3 $(DEV_DIR)/get_vale_conf.py + @echo '.Name=="Canonical.400-Enforce-inclusive-terms"' > $(DEV_DIR)/styles/woke.filter + @echo '.Level=="error" and .Name!="Canonical.500-Repeated-words" and .Name!="Canonical.000-US-spellcheck"' > $(DEV_DIR)/styles/error.filter + @echo '.Name=="Canonical.000-US-spellcheck"' > $(DEV_DIR)/styles/spelling.filter + @. $(DOCS_VENV); find $(VALE_DIR)/vale_bin -size 195c -exec vale --version \; woke: vale-install - @cat $(SPHINXDIR)/styles/config/vocabularies/Canonical/accept.txt > $(SPHINXDIR)/styles/config/vocabularies/Canonical/accept_backup.txt - @cat $(SPHINXDIR)/.wordlist.txt $(SOURCEDIR)/.custom_wordlist.txt >> $(SPHINXDIR)/styles/config/vocabularies/Canonical/accept.txt - @echo "Running Vale acceptable term check against $(TARGET). To change target set TARGET= with make command" - @. $(VENV); vale --config="$(VALE_CONFIG)" --filter='$(SPHINXDIR)/styles/woke.filter' --glob='*.{md,rst}' $(TARGET) - @cat $(SPHINXDIR)/styles/config/vocabularies/Canonical/accept_backup.txt > $(SPHINXDIR)/styles/config/vocabularies/Canonical/accept.txt && rm $(SPHINXDIR)/styles/config/vocabularies/Canonical/accept_backup.txt + @cat $(DOCS_VOCAB)/accept.txt > $(DOCS_VOCAB)/accept_backup.txt + @cat $(DOCS_SOURCEDIR)/.custom_wordlist.txt >> $(DOCS_VOCAB)/accept.txt + @echo "Running Vale acceptable term check against $(CHECK_PATH). To change target set CHECK_PATH= with make command" + @. $(DOCS_VENV); vale --config="$(VALE_CONFIG)" --filter='$(DEV_DIR)/styles/woke.filter' --glob='*.{md,rst}' $(CHECK_PATH) + @cat $(DOCS_VOCAB)/accept_backup.txt > $(DOCS_VOCAB)/accept.txt && rm $(DOCS_VOCAB)/accept_backup.txt vale: vale-install - @cat $(SPHINXDIR)/styles/config/vocabularies/Canonical/accept.txt > $(SPHINXDIR)/styles/config/vocabularies/Canonical/accept_backup.txt - @cat $(SPHINXDIR)/.wordlist.txt $(SOURCEDIR)/.custom_wordlist.txt >> $(SPHINXDIR)/styles/config/vocabularies/Canonical/accept.txt - @echo "Running Vale against $(TARGET). To change target set TARGET= with make command" - @. $(VENV); vale --config="$(VALE_CONFIG)" --filter='$(SPHINXDIR)/styles/error.filter' --glob='*.{md,rst}' $(TARGET) - @cat $(SPHINXDIR)/styles/config/vocabularies/Canonical/accept_backup.txt > $(SPHINXDIR)/styles/config/vocabularies/Canonical/accept.txt && rm $(SPHINXDIR)/styles/config/vocabularies/Canonical/accept_backup.txt - -vale-spelling: vale-install - @cat $(SPHINXDIR)/styles/config/vocabularies/Canonical/accept.txt > $(SPHINXDIR)/styles/config/vocabularies/Canonical/accept_backup.txt - @cat $(SPHINXDIR)/.wordlist.txt $(SOURCEDIR)/.custom_wordlist.txt >> $(SPHINXDIR)/styles/config/vocabularies/Canonical/accept.txt - @echo "Running Vale against $(TARGET). To change target set TARGET= with make command" - @. $(VENV); vale --config="$(VALE_CONFIG)" --filter='$(SPHINXDIR)/styles/spelling.filter' --glob='*.{md,rst}' $(TARGET) - @cat $(SPHINXDIR)/styles/config/vocabularies/Canonical/accept_backup.txt > $(SPHINXDIR)/styles/config/vocabularies/Canonical/accept.txt && rm $(SPHINXDIR)/styles/config/vocabularies/Canonical/accept_backup.txt + @cat $(DOCS_VOCAB)/accept.txt > $(DOCS_VOCAB)/accept_backup.txt + @cat $(DOCS_SOURCEDIR)/.custom_wordlist.txt >> $(DOCS_VOCAB)/accept.txt + @echo "Running Vale against $(CHECK_PATH). To change target set CHECK_PATH= with make command" + @. $(DOCS_VENV); vale --config="$(VALE_CONFIG)" --filter='$(DEV_DIR)/styles/error.filter' --glob='*.{md,rst}' $(CHECK_PATH) + @cat $(DOCS_VOCAB)/accept_backup.txt > $(DOCS_VOCAB)/accept.txt && rm $(DOCS_VOCAB)/accept_backup.txt + +spelling: vale-install + @cat $(DOCS_VOCAB)/accept.txt > $(DOCS_VOCAB)/accept_backup.txt + @cat $(DOCS_SOURCEDIR)/.custom_wordlist.txt >> $(DOCS_VOCAB)/accept.txt + @echo "Running Vale against $(CHECK_PATH). To change target set CHECK_PATH= with make command" + @. $(DOCS_VENV); vale --config="$(VALE_CONFIG)" --filter='$(DEV_DIR)/styles/spelling.filter' --glob='*.{md,rst}' $(CHECK_PATH) + @cat $(DOCS_VOCAB)/accept_backup.txt > $(DOCS_VOCAB)/accept.txt && rm $(DOCS_VOCAB)/accept_backup.txt + +spellcheck: spelling + @echo "Please note that the \`make spellcheck\` command is being deprecated in favor of \`make spelling\`" pdf-prep: install - @for packageName in $(REQPDFPACKS); do (dpkg-query -W -f='$${Status}' $$packageName 2>/dev/null | \ + @for packageName in $(DOCS_PDFPACKAGES); do (dpkg-query -W -f='$${Status}' $$packageName 2>/dev/null | \ grep -c "ok installed" >/dev/null && echo "Package $$packageName is installed") && continue || \ - (echo; echo "PDF generation requires the installation of the following packages: $(REQPDFPACKS)" && \ + (echo; echo "PDF generation requires the installation of the following packages: $(DOCS_PDFPACKAGES)" && \ echo "" && echo "Run 'sudo make pdf-prep-force' to install these packages" && echo "" && echo \ "Please be aware these packages will be installed to your system") && exit 1 ; done pdf-prep-force: apt-get update apt-get upgrade -y - apt-get install --no-install-recommends -y $(REQPDFPACKS) \ + apt-get install --no-install-recommends -y $(DOCS_PDFPACKAGES) \ pdf: pdf-prep - @. $(VENV); sphinx-build -M latexpdf "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) - @rm ./$(BUILDDIR)/latex/front-page-light.pdf || true - @rm ./$(BUILDDIR)/latex/normal-page-footer.pdf || true - @find ./$(BUILDDIR)/latex -name "*.pdf" -exec mv -t ./$(BUILDDIR) {} + - @rm -r $(BUILDDIR)/latex + @. $(DOCS_VENV); $(SPHINX_BUILD) -M latexpdf "$(DOCS_SOURCEDIR)" "$(DOCS_BUILDDIR)" $(SPHINX_OPTS) + @rm ./$(DOCS_BUILDDIR)/latex/front-page-light.pdf || true + @rm ./$(DOCS_BUILDDIR)/latex/normal-page-footer.pdf || true + @find ./$(DOCS_BUILDDIR)/latex -name "*.pdf" -exec mv -t ./$(DOCS_BUILDDIR) {} + + @rm -r $(DOCS_BUILDDIR)/latex @echo - @echo "Output can be found in ./$(BUILDDIR)" + @echo "Output can be found in ./$(DOCS_BUILDDIR)" @echo -allmetrics: html - @echo "Recording documentation metrics..." - @echo "Checking for existence of vale..." - . $(VENV) - @. $(VENV); test -d $(SPHINXDIR)/venv/lib/python*/site-packages/vale || pip install vale - @. $(VENV); test -f $(VALE_CONFIG) || python3 $(SPHINXDIR)/get_vale_conf.py - @. $(VENV); find $(SPHINXDIR)/venv/lib/python*/site-packages/vale/vale_bin -size 195c -exec vale --config "$(VALE_CONFIG)" $(TARGET) > /dev/null \; - @eval '$(METRICSDIR)/source_metrics.sh $(PWD)' - @eval '$(METRICSDIR)/build_metrics.sh $(PWD) $(METRICSDIR)' - update: install - @. $(VENV); .sphinx/update_sp.py + @. $(DOCS_VENV); _dev/update_sp.py # Catch-all target: route all unknown targets to Sphinx using the new -# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +# "make mode" option. $(O) is meant as a shortcut for $(SPHINX_OPTS). %: - . $(VENV); $(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + $(MAKE) --no-print-directory install + . $(DOCS_VENV); $(SPHINX_BUILD) -M $@ "$(DOCS_SOURCEDIR)" "$(DOCS_BUILDDIR)" $(SPHINX_OPTS) $(O) diff --git a/docs/.sphinx/.markdownlint.json b/docs/_dev/.markdownlint.json similarity index 99% rename from docs/.sphinx/.markdownlint.json rename to docs/_dev/.markdownlint.json index 536f9ea9..1ad0a01d 100644 --- a/docs/.sphinx/.markdownlint.json +++ b/docs/_dev/.markdownlint.json @@ -18,4 +18,4 @@ "MD042": true, "MD045": true, "MD052": true -} \ No newline at end of file +} diff --git a/docs/.sphinx/.pre-commit-config.yaml b/docs/_dev/.pre-commit-config.yaml similarity index 100% rename from docs/.sphinx/.pre-commit-config.yaml rename to docs/_dev/.pre-commit-config.yaml diff --git a/docs/_dev/.pymarkdown.json b/docs/_dev/.pymarkdown.json new file mode 100644 index 00000000..2c4c669d --- /dev/null +++ b/docs/_dev/.pymarkdown.json @@ -0,0 +1,46 @@ +{ + "plugins": { + "selectively_enable_rules": true, + "heading-style": { + "enabled": true, + "style": "atx" + }, + "commands-show-output": { + "enabled": true + }, + "no-missing-space-atx": { + "enabled": true + }, + "blanks-around-headings": { + "enabled": true + }, + "heading-start-left": { + "enabled": true + }, + "no-trailing-punctuation": { + "enabled": true, + "punctuation": ".,;。,;" + }, + "blanks-around-fences": { + "enabled": true, + "list_items": false + }, + "blanks-around-lists": { + "enabled": true + }, + "hr-style": { + "enabled": true + }, + "no-empty-links": { + "enabled": true + }, + "no-alt-text": { + "enabled": true + } + }, + "extensions": { + "front-matter" : { + "enabled" : true + } + } +} diff --git a/docs/.sphinx/get_vale_conf.py b/docs/_dev/get_vale_conf.py old mode 100644 new mode 100755 similarity index 92% rename from docs/.sphinx/get_vale_conf.py rename to docs/_dev/get_vale_conf.py index 46f57d89..b09404ae --- a/docs/.sphinx/get_vale_conf.py +++ b/docs/_dev/get_vale_conf.py @@ -15,9 +15,9 @@ datefmt='%Y-%m-%d %H:%M:%S' ) -SPHINX_DIR = os.path.join(os.getcwd(), ".sphinx") +DEV_DIR = os.path.join(os.getcwd(), "_dev") -GITHUB_REPO = "canonical/praecepta" +GITHUB_REPO = "canonical/documentation-style-guide" GITHUB_CLONE_URL = f"https://github.com/{GITHUB_REPO}.git" # Source paths to copy from repo @@ -31,12 +31,12 @@ def clone_repo_and_copy_paths(file_source_dest, overwrite=False): """ Clone the repository to a temporary directory and copy required files - + Args: file_source_dest: dictionary of file paths to copy from the repository, and their destination paths overwrite: boolean flag to overwrite existing files in the destination - + Returns: bool: True if all files were copied successfully, False otherwise """ @@ -52,8 +52,8 @@ def clone_repo_and_copy_paths(file_source_dest, overwrite=False): try: result = subprocess.run( - clone_cmd, - capture_output=True, + clone_cmd, + capture_output=True, text=True, check=True ) @@ -73,7 +73,7 @@ def clone_repo_and_copy_paths(file_source_dest, overwrite=False): continue if not copy_files_to_path(source_path, dest, overwrite): - is_copy_success = False + is_copy_success = False logging.error("Failed to copy %s to %s", source_path, dest) # Clean up temporary directory @@ -85,12 +85,12 @@ def clone_repo_and_copy_paths(file_source_dest, overwrite=False): def copy_files_to_path(source_path, dest_path, overwrite=False): """ Copy a file or directory from source to destination - + Args: source_path: Path to the source file or directory dest_path: Path to the destination overwrite: Boolean flag to overwrite existing files in the destination - + Returns: bool: True if copy was successful, False otherwise """ @@ -133,12 +133,12 @@ def parse_arguments(): def main(): # Define local directory paths - vale_files_dict = {file: os.path.join(SPHINX_DIR, file) for file in VALE_FILE_LIST} + vale_files_dict = {file: os.path.join(DEV_DIR, file) for file in VALE_FILE_LIST} # Parse command line arguments, default to overwrite_enabled = True overwrite_enabled = not parse_arguments().no_overwrite - # Download into /tmp through git clone + # Download into /tmp through git clone if not clone_repo_and_copy_paths(vale_files_dict, overwrite=overwrite_enabled): logging.error("Failed to download files from repository") return 1 diff --git a/docs/.sphinx/pa11y.json b/docs/_dev/pa11y.json similarity index 100% rename from docs/.sphinx/pa11y.json rename to docs/_dev/pa11y.json diff --git a/docs/.sphinx/update_sp.py b/docs/_dev/update_sp.py similarity index 83% rename from docs/.sphinx/update_sp.py rename to docs/_dev/update_sp.py index 44c10d9b..3014a84f 100755 --- a/docs/.sphinx/update_sp.py +++ b/docs/_dev/update_sp.py @@ -1,29 +1,32 @@ #! /usr/bin/env python -# Initial update script for the starter pack. +# Initial update script for the Sphinx Stack. # # Requires some manual intervention, but makes identifying updates and differences easier. # # For debugging, please run this script with DEBUGGING=1 -# e.g. user@device:~/git/Canonical/sphinx-docs-starter-pack/docs$ DEBUGGING=1 python .sphinx/update_sp.py +# e.g. user@device:~/git/Canonical/sphinx-stack/docs$ DEBUGGING=1 python _dev/update_sp.py import glob import logging import os -import requests import re import subprocess import sys -from requests.exceptions import RequestException + +import requests from packaging.version import parse as parse_version +from requests.exceptions import RequestException -SPHINX_DIR = os.path.join(os.getcwd(), ".sphinx") +SPHINX_DIR = os.path.abspath(os.path.dirname(__file__)) +DOCS_DIR = os.path.abspath(os.path.join(SPHINX_DIR, "..")) +REQUIREMENTS = os.path.join(DOCS_DIR, "requirements.txt") SPHINX_UPDATE_DIR = os.path.join(SPHINX_DIR, "update") -GITHUB_REPO = "canonical/sphinx-docs-starter-pack" +GITHUB_REPO = "canonical/sphinx-stack" GITHUB_API_BASE = f"https://api.github.com/repos/{GITHUB_REPO}" -GITHUB_API_SPHINX_DIR = f"{GITHUB_API_BASE}/contents/docs/.sphinx" -GITHUB_RAW_BASE = f"https://raw.githubusercontent.com/{GITHUB_REPO}/check-log" +GITHUB_API_DEV_DIR = f"{GITHUB_API_BASE}/contents/docs/_dev" +GITHUB_RAW_BASE = f"https://raw.githubusercontent.com/{GITHUB_REPO}/main" TIMEOUT = 10 # seconds @@ -41,7 +44,7 @@ def main(): except FileNotFoundError: print("WARNING\nWARNING\nWARNING") print( - "You need to update to at least version 1.0.0 of the starter pack to start using the update function." + "You need to update to at least version 1.0.0 of the Sphinx Stack to start using the update function." ) print("You may experience issues using this functionality.") logging.debug("No local version found. Setting version to None") @@ -59,15 +62,15 @@ def main(): logging.debug("Comparing versions") if parse_version(local_version) < parse_version(latest_release): logging.debug("Local version is older than the release version.") - print("Starter pack is out of date.\n") + print("Sphinx Stack is out of date.\n") - # Identify and download '.sphinx' dir files to '.sphinx/update' + # Identify and download '_dev' dir files to '_dev/update' files_updated, new_files = update_static_files() - # Write new version to file to '.sphinx/update' + # Write new version to file to '_dev/update' download_file( - GITHUB_RAW_BASE + "/docs/.sphinx/version", + GITHUB_RAW_BASE + "/docs/_dev/version", os.path.join(SPHINX_UPDATE_DIR, "version"), ) @@ -82,8 +85,8 @@ def main(): if files_updated: logging.debug("Updated files found and downloaded") print("Differences have been identified in static files.") - print("Updated files have been downloaded to '.sphinx/update'.") - print("Validate and move these files into your '.sphinx/' directory.") + print("Updated files have been downloaded to '_dev/update'.") + print("Validate and move these files into your '_dev/' directory.") else: logging.debug("No files found to update") # Provide information on NEW files @@ -92,7 +95,7 @@ def main(): print( "NOTE: New files have been downloaded\n", "See 'NEWFILES.txt' for all downloaded files\n", - "Validate and merge these files into your '.sphinx/' directory", + "Validate and merge these files into your '_dev/' directory", ) else: logging.debug("No new files found to download") @@ -103,7 +106,7 @@ def main(): # Check requirements are the same new_requirements = [] try: - with open("requirements.txt", "r") as file: + with open(REQUIREMENTS, "r") as file: logging.debug("Checking requirements") local_reqs = set(file.read().splitlines()) - {""} @@ -113,7 +116,7 @@ def main(): new_requirements = requirements - local_reqs - for req in requirements - local_reqs: + for req in new_requirements: logging.debug(f"{req} not found in local requirements.txt") for req in requirements & local_reqs: @@ -121,26 +124,26 @@ def main(): if new_requirements != set(): print( - "You may need to add the following pacakges to your requirements.txt file:" + "You may need to add the following packages to your requirements.txt file:" ) for r in new_requirements: print(f"{r}\n") except FileNotFoundError: print("requirements.txt not found") print( - "The updated starter pack has moved requirements.txt out of the '.sphinx' dir" + "The updated Sphinx Stack has moved requirements.txt out of the '_dev' dir" ) print("requirements.txt not checked, please update your requirements manually") def update_static_files(): - """Checks local files against remote for new and different files, downloads to '.sphinx/updates'""" + """Checks local files against remote for new and different files, downloads to '_dev/updates'""" files, paths = get_local_files_and_paths() new_file_list = [] - for item in query_api(GITHUB_API_SPHINX_DIR).json(): + for item in query_api(GITHUB_API_DEV_DIR).json(): logging.debug(f"Checking {item['name']}") - # Checks existing files in '.sphinx' starter pack static root for changed SHA + # Checks existing files in '_dev' Sphinx Stack static root for changed SHA if item["name"] in files and item["type"] == "file": index = files.index(item["name"]) if item["sha"] != get_git_revision_hash(paths[index]): @@ -152,17 +155,15 @@ def update_static_files(): # Indicate update script needs to be updated and re-run print("WARNING") print( - "THIS UPDATE SCRIPT IS OUT OF DATE. YOU MAY NEED TO RUN ANOTHER UPDATE AFTER UPDATING TO THE FILE IN '.sphinx/updates'." + "THIS UPDATE SCRIPT IS OUT OF DATE. YOU MAY NEED TO RUN ANOTHER UPDATE AFTER UPDATING TO THE FILE IN '_dev/updates'." ) print("WARNING\n") else: logging.debug("File hashes are equal") - # Checks nested files '.sphinx/**/**.*' for changed SHA (single level of depth) + # Checks nested files '_dev/**/**.*' for changed SHA (single level of depth) elif item["type"] == "dir": logging.debug(item["name"] + " is a directory") - for nested_item in query_api( - f"{GITHUB_API_SPHINX_DIR}/{item['name']}" - ).json(): + for nested_item in query_api(f"{GITHUB_API_DEV_DIR}/{item['name']}").json(): logging.debug(f"Checking {nested_item['name']}") if nested_item["name"] in files: index = files.index(nested_item["name"]) @@ -187,7 +188,7 @@ def update_static_files(): SPHINX_UPDATE_DIR, item["name"], nested_item["name"] ), ) - # Downloads NEW files in '.sphinx' starter pack static root + # Downloads NEW files in '_dev' Sphinx Stack static root else: if item["type"] == "file": logging.debug(f"No local version found of {item['name']}") @@ -206,7 +207,7 @@ def update_static_files(): # Writes return value for parent function if new_file_list != []: # Provides more information on new files - with open("NEWFILES.txt", "w") as f: + with open(f"{SPHINX_DIR}/NEWFILES.txt", "w") as f: for entry in new_file_list: f.write(f"{entry}\n") logging.debug("Some downloaded files are new") @@ -223,12 +224,12 @@ def get_git_revision_hash(file) -> str: # Examines local files def get_local_files_and_paths(): - """Identify '.sphinx' local files and paths""" + """Identify '_dev' local files and paths""" logging.debug("Checking local files and paths") try: files = [] paths = [] - patterns = [".*", "**.*", "metrics/**.*"] + patterns = [".*", "**.*"] files, paths = [], [] for pattern in patterns: diff --git a/docs/_dev/version b/docs/_dev/version new file mode 100644 index 00000000..cd5ac039 --- /dev/null +++ b/docs/_dev/version @@ -0,0 +1 @@ +2.0 diff --git a/docs/_static/.gitkeep b/docs/_static/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/docs/conf.py b/docs/conf.py index 3404ab31..452c9c79 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,5 +1,6 @@ import datetime import os +import textwrap import yaml # Configuration for the Sphinx documentation builder. @@ -8,232 +9,210 @@ # A complete list of built-in Sphinx configuration values: # https://www.sphinx-doc.org/en/master/usage/configuration.html # -# Our starter pack uses the custom Canonical Sphinx extension -# to keep all documentation based on it consistent and on brand: +# The Sphinx Stack uses the Canonical Sphinx theme to keep all documentation consistent +# and on brand: # https://github.com/canonical/canonical-sphinx - ####################### # Project information # ####################### # Project name - project = "MicroCeph" -author = "Canonical Ltd." +# Author name; used in the default copyright statement in the page footer +author = "Canonical Ltd." -# Sidebar documentation title; best kept reasonably short -# -# To include a version number, add it here (hardcoded or automated). -# -# To disable the title, set to an empty string. +# The year in the copyright statement +copyright = f"{datetime.date.today().year}" +# Sidebar documentation title +# To disable the title, set it to an empty string. html_title = project + " documentation" - -# Copyright string; shown at the bottom of the page -# -# Now, the starter pack uses CC-BY-SA as the license -# and the current year as the copyright year. -# -# If your docs need another license, specify it instead of 'CC-BY-SA'. -# -# If your documentation is a part of the code repository of your project, -# it inherits the code license instead; specify it instead of 'CC-BY-SA'. -# -# NOTE: For static works, it is common to provide the first publication year. -# Another option is to provide both the first year of publication -# and the current year, especially for docs that frequently change, -# e.g. 2022–2023 (note the en-dash). -# -# A way to check a repo's creation date is to get a classic GitHub token -# with 'repo' permissions; see https://github.com/settings/tokens -# Next, use 'curl' and 'jq' to extract the date from the API's output: -# -# curl -H 'Authorization: token ' \ -# -H 'Accept: application/vnd.github.v3.raw' \ -# https://api.github.com/repos/canonical/ | jq '.created_at' - -copyright = "%s AGPL-3.0, %s" % (datetime.date.today().year, author) - - # Documentation website URL -# -# Update with the official URL of your docs or leave empty if unsure. -# -# NOTE: The Open Graph Protocol (OGP) enhances page display in a social graph -# and is used by social media platforms; see https://ogp.me/ - -ogp_site_url = "https://canonical-microceph.readthedocs-hosted.com/" - +ogp_site_url = os.environ.get("READTHEDOCS_CANONICAL_URL", "/") # Preview name of the documentation website -# -# To use a different name for the project in previews, update as needed. - +# TODO: To use a different name for the project in previews, update the next line. ogp_site_name = project - # Preview image URL -# -# To customise the preview image, update as needed. - -ogp_image = "https://assets.ubuntu.com/v1/253da317-image-document-ubuntudocs.svg" - +# TODO: To customise the preview image, update the next line. +ogp_image = "https://assets.ubuntu.com/v1/cc828679-docs_illustration.svg" # Product favicon; shown in bookmarks, browser tabs, etc. - -# To customise the favicon, uncomment and update as needed. - -# html_favicon = '.sphinx/_static/favicon.png' - +# TODO: To customise the favicon, uncomment and update the next line. +# html_favicon = "_static/favicon.png" # Dictionary of values to pass into the Sphinx context for all pages: # https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-html_context - html_context = { # Product page URL; can be different from product docs URL - # - # Change to your product website URL, - # dropping the 'https://' prefix, e.g. 'ubuntu.com/lxd'. - # - # TODO: If there's no such website, - # remove the {{ product_page }} link from the page header template - # (usually .sphinx/_templates/header.html; also, see README.rst). - "product_page": "", + # TODO: Change to your product website URL, dropping the 'https://' prefix (e.g., + # 'ubuntu.com/lxd'). If there's no such website, remove the {{ product_page }} + # link from the _templates/header.html file. + "product_page": "canonical.com/ceph", + # Product tag image; the orange part of your logo, shown in the page header - # - # To add a tag image, uncomment and update as needed. + # TODO: To add a tag image, uncomment and update as needed. # 'product_tag': '_static/tag.png', + # Your Discourse instance URL - # - # Change to your Discourse instance URL or leave empty. - # - # If set, adding ':discourse: 123' to an .rst file - # will add a link to Discourse topic 123 at the bottom of the page. + # TODO: Change to your Discourse instance URL or leave empty. "discourse": "", + # Your Mattermost channel URL - # - # Change to your Mattermost channel URL or leave empty. + # TODO: Change to your Mattermost channel URL or leave empty. "mattermost": "https://chat.canonical.com/canonical/channels/ceph", + # Your Matrix channel URL - # - # Change to your Matrix channel URL or leave empty. + # TODO: Change to your Matrix channel URL or leave empty. "matrix": "https://matrix.to/#/#ceph-general:ubuntu.com", - # Your documentation GitHub repository URL - # - # Change to your documentation GitHub repository URL or leave empty. - # - # NOTE: If set, links for viewing the documentation source files - # and creating GitHub issues are added at the bottom of each page. + + # Your documentation GitHub repository URL If set, links for viewing the + # documentation source files and creating GitHub issues are added at the bottom of + # each page. + # TODO: Change to your documentation GitHub repository URL or leave empty. "github_url": "https://github.com/canonical/microceph", - # Docs branch in the repo; used in links for viewing the source files - # - # To customise the branch, uncomment and update as needed. - 'repo_default_branch': 'main', - # Docs location in the repo; used in links for viewing the source files - # + # Docs branch in the repo; used in links for viewing the source files + "repo_default_branch": "main", - # To customise the directory, uncomment and update as needed. + # Docs location in the repo; used in links for viewing the source files "repo_folder": "/docs/", - # To enable or disable the Previous / Next buttons at the bottom of pages + + # TODO: To enable or disable the Previous / Next buttons at the bottom of pages # Valid options: none, prev, next, both "sequential_nav": "both", - # To enable listing contributors on individual pages, set to True + + # TODO: To enable listing contributors on individual pages, set to True "display_contributors": True, - # Required for feedback button - 'github_issues': 'enabled', + # Required for feedback button + "github_issues": "enabled", + + # Passes the top-level 'author' value to the theme + "author": author, + + # Documentation license information + "license": { + # TODO: Specify your project's license. + # For the name, we recommend using the standard shorthand identifier from + # https://spdx.org/licenses + "name": "AGPL-3.0", + # TODO: Link directly to your project's license statement. + "url": "https://github.com/canonical/microceph/blob/main/COPYING", + }, } -# To enable the edit button on pages, uncomment and change the link to a +# TODO: To enable the edit button on pages, uncomment and change the link to a # public repository on GitHub or Launchpad. Any of the following link domains # are accepted: -# - https://github.com/example-org/example" +# - https://github.com/canonical/microceph" # - https://launchpad.net/example # - https://git.launchpad.net/example -# html_theme_options = { 'source_edit_link': 'https://github.com/canonical/microceph', } -# Project slug; see https://meta.discourse.org/t/what-is-category-slug/87897 -# -# If your documentation is hosted on https://docs.ubuntu.com/, -# uncomment and update as needed. - +# Project slug +# TODO: If your documentation is hosted on https://documentation.ubuntu.com/, +# uncomment and set to the RTD slug. # slug = '' -####################### +############################################################### # Sitemap configuration: https://sphinx-sitemap.readthedocs.io/ -####################### +############################################################### -# Base URL of RTD hosted project +# Use RTD canonical URL to ensure duplicate pages have a specific canonical URL +html_baseurl = os.environ.get("READTHEDOCS_CANONICAL_URL", "/") -html_baseurl = 'https://canonical-microceph.readthedocs-hosted.com/' +# sphinx-sitemap uses html_baseurl to generate the full URL for each page: +sitemap_url_scheme = "{link}" -# URL scheme. Add language and version scheme elements. -# When configured with RTD variables, check for RTD environment so manual runs succeed: +# Include `lastmod` dates in the sitemap: +sitemap_show_lastmod = True +# URL scheme. Add language and version scheme elements +# When configured with RTD variables, check for RTD environment so manual runs succeed: if 'READTHEDOCS_VERSION' in os.environ: version = os.environ["READTHEDOCS_VERSION"] sitemap_url_scheme = '{version}{link}' else: sitemap_url_scheme = 'MANUAL/{link}' -# Template and asset locations -#html_static_path = ["_static"] -templates_path = ["_templates"] +# TODO: Exclude pages that aren't user-facing from the sitemap (e.g., module pages +# generated by autodoc). +# Pages excluded from the sitemap: +sitemap_excludes = [ + "404/", + "genindex/", + "search/", +] + +################################ +# Template and asset locations # +################################ +html_static_path = ["_static"] +templates_path = ["_templates"] ############# # Redirects # ############# -# To set up redirects: https://documatt.gitlab.io/sphinx-reredirects/usage.html -# For example: 'explanation/old-name.html': '../how-to/prettify.html', +# Add redirects to the 'redirects.txt' file +# https://sphinxext-rediraffe.readthedocs.io/en/latest/ # To set up redirects in the Read the Docs project dashboard: # https://docs.readthedocs.io/en/stable/guides/redirects.html -# NOTE: If undefined, set to None, or empty, -# the sphinx_reredirects extension will be disabled. +rediraffe_redirects = "redirects.txt" -redirects = { - # The FDE topic was split to a how-to and explanation; explanation topic was renamed - 'explanation/security/full-disk-encryption': '../../security/about-fde', -} +# Strips '/index.html' from destination URLs when building with 'dirhtml' +rediraffe_dir_only = True + +############################ +# sphinx-llm configuration # +############################ + +# This description is included in llms.txt to provide some initial context for your +# product docs. +# TODO: Add a description in the form "This is the documentation for , +# ". +llms_txt_description = textwrap.dedent( + """\ + This is the official documentation for MicroCeph, an opinionated orchestration tool for Ceph clusters at all scales, and the easiest way to get up and running with Ceph. + """ +) ########################### # Link checker exceptions # ########################### # A regex list of URLs that are ignored by 'make linkcheck' -# # Remove or adjust the ACME entry after you update the contributing guide - linkcheck_ignore = [ "http://127.0.0.1:8000", "https://github.com/canonical/ACME/*", - "https://matrix.to/#/#ceph-general:ubuntu.com", - "https://matrix.to/#/#documentation:ubuntu.com", - "https://matrix.to/#/#ceph-devel:ubuntu.com", - "https://matrix.to/#/#ubuntu-ceph:matrix.org" - ] - -# A regex list of URLs where anchors are ignored by 'make linkcheck' + "https://github.com", + "https://matrix\.to/.*", + "https://example.com", + "https://tracker.ceph.com/.*", +] +# A regex list of URLs where anchors are ignored by 'make linkcheck linkcheck_anchors_ignore_for_url = [ r"https://github\.com/.*", - r"https://matrix.to/#/#ceph-general:ubuntu.com", - r"https://matrix.to/#/#documentation:ubuntu.com", - r"https://matrix.to/#/#ceph-devel:ubuntu.com", - r"https://matrix.to/#/#ubuntu-ceph:matrix.org" + r"https://matrix.to/*", + # SourceForge domains often block linkcheck + r"https://.*\.sourceforge\.(net|io)/.*", ] +# How long the link checker will wait for a response for each request +# TODO: Decrease to improve run time or increase if links frequently time out. # External documentation sites (canonical.com, ubuntu.com, ...) intermittently # return 429 (rate limiting), 502 (bad gateway), or read timeouts while the # link checker is running. These are transient infra failures, not broken @@ -251,17 +230,16 @@ # Custom MyST syntax extensions; see # https://myst-parser.readthedocs.io/en/latest/syntax/optional.html -# # NOTE: By default, the following MyST extensions are enabled: -# substitution, deflist, linkify - +# - substitution +# - deflist +# - linkify # myst_enable_extensions = set() - # Custom Sphinx extensions; see # https://www.sphinx-doc.org/en/master/usage/extensions/index.html -# NOTE: The canonical_sphinx extension is required for the starter pack. +# NOTE: The canonical_sphinx extension is required for the Shinx Stack. # It automatically enables the following extensions: # - custom-rst-roles # - myst_parser @@ -275,9 +253,24 @@ # - sphinxext.opengraph # - terminal-output # - youtube-links - extensions = [ "canonical_sphinx", + "notfound.extension", + "sphinx_design", + "sphinx_rerediraffe", + "sphinx_reredirects", + "sphinx_tabs.tabs", + "sphinxcontrib.jquery", + "sphinxext.opengraph", + "sphinx_config_options", + "sphinx_contributor_listing", + "sphinx_filtered_toctree", + "sphinx_llm.txt", + "sphinx_related_links", + "sphinx_roles", + "sphinx_terminal", + "sphinx_ubuntu_images", + "sphinx_youtube_links", "sphinxcontrib.cairosvgconverter", "sphinx_last_updated_by_git", "sphinx.ext.intersphinx", @@ -285,52 +278,40 @@ ] # Excludes files or directories from processing - exclude_patterns = [ "doc-cheat-sheet*", + ".venv*", ] -# Adds custom CSS files, located under 'html_static_path' - +# Adds custom CSS files, located remotely or in 'html_static_path'. html_css_files = ["https://assets.ubuntu.com/v1/d86746ef-cookie_banner.css"] - # Adds custom JavaScript files, located under 'html_static_path' html_js_files = ["https://assets.ubuntu.com/v1/287a5e8f-bundle.js"] -# Specifies a reST snippet to be appended to each .rst file - -rst_epilog = """ -.. include:: /reuse/links.txt -.. include:: /reuse/substitutions.txt -""" +# Appends extra markup to the end of every document written in reST +# rst_epilog = """ +# """ # Feedback button at the top; enabled by default -# -# To disable the button, uncomment this. - +# TODO: Disable the button if your project is unsuitable for public feedback. # disable_feedback_button = True - # Your manpage URL -# -# To enable manpage links, uncomment and replace {codename} with required +# TODO: To enable manpage links, uncomment and replace {codename} with required # release, preferably an LTS release (e.g. noble). Do *not* substitute # {section} or {page}; these will be replaced by sphinx at build time # # NOTE: If set, adding ':manpage:' to an .rst file # adds a link to the corresponding man section at the bottom of the page. - # manpages_url = 'https://manpages.ubuntu.com/manpages/{codename}/en/' + \ # 'man{section}/{page}.{section}.html' - # Specifies a reST snippet to be prepended to each .rst file # This defines a :center: role that centers table cell content. # This defines a :h2: role that styles content for use with PDF generation. - rst_prolog = """ .. role:: center :class: align-center @@ -363,6 +344,8 @@ # The second tuple element (None) means Sphinx fetches objects.inv automatically # from the base URL. +# Configuration for Intersphinx projects + intersphinx_mapping = { # Upstream Ceph documentation 'upstream-ceph': ('https://docs.ceph.com/en/latest/', None), diff --git a/docs/redirects.txt b/docs/redirects.txt new file mode 100644 index 00000000..e69de29b diff --git a/docs/requirements.txt b/docs/requirements.txt index 77ec0062..c8c0535c 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,5 +1,34 @@ -canonical-sphinx[full] -packaging -sphinxcontrib-svg2pdfconverter[CairoSVG] -sphinx-last-updated-by-git -sphinx-sitemap +# Canonical theme (still needed for Furo theme and custom templates) +canonical-sphinx~=0.6 + +# Extensions previously auto-loaded by canonical-sphinx +myst-parser~=4.0 # v5.0.0 causes version conflicts +sphinx-autobuild +sphinx-design==0.6.1 +sphinx-notfound-page~=1.1 +sphinx-reredirects==0.1.6 +sphinx-tabs~=3.5 +sphinxcontrib-jquery~=4.1 +sphinxext-opengraph~=0.13 +sphinx-rerediraffe>=0.0.3, <1.0.0 + +# Extra extensions, previously bundled as canonical-sphinx-extensions +sphinx-config-options~=0.1 +sphinx-contributor-listing~=0.1 +sphinx-filtered-toctree~=0.1 +sphinx-related-links~=0.1 +sphinx-roles~=0.1 +sphinx-terminal~=1.0 +sphinx-ubuntu-images~=0.1 +sphinx-youtube-links~=0.1 + +# Other dependencies +packaging~=26.1 +sphinxcontrib-svg2pdfconverter[CairoSVG]~=2.1 +sphinx-last-updated-by-git~=0.3 +sphinx-sitemap~=2.9 +sphinx-llm~=0.4 + +# Vale dependencies +rst2html +vale~=3.13 diff --git a/docs/reuse/links.txt b/docs/reuse/links.txt deleted file mode 100644 index 0ac9bfba..00000000 --- a/docs/reuse/links.txt +++ /dev/null @@ -1,43 +0,0 @@ -.. _Canonical Documentation Style Guide: https://docs.ubuntu.com/styleguide/en -.. _Canonical Reference Library: https://library.canonical.com/ -.. _Canonical Sphinx: https://github.com/canonical/canonical-sphinx -.. _change log: https://github.com/canonical/sphinx-docs-starter-pack/wiki/Change-log -.. _Diátaxis: https://diataxis.fr/ -.. _Example product documentation: https://canonical-example-product-documentation.readthedocs-hosted.com/ -.. _Example product documentation repository: https://github.com/canonical/example-product-documentation -.. _`file-wide metadata`: https://www.sphinx-doc.org/en/master/usage/restructuredtext/field-lists.html -.. _Five golden rules for compliant alt text: https://abilitynet.org.uk/news-blogs/five-golden-rules-compliant-alt-text -.. _`Furo documentation`: https://pradyunsg.me/furo/quickstart/ -.. _grid tables: https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#grid-tables -.. _`Hiding Contents sidebar`: https://pradyunsg.me/furo/customisation/toc/ -.. _How to connect your Read the Docs account to your Git provider: https://docs.readthedocs.com/platform/stable/guides/connecting-git-account.html -.. _How to manually configure a Git repository integration: https://docs.readthedocs.io/en/stable/guides/setup/git-repo-manual.html -.. _How to publish documentation on Read the Docs: https://library.canonical.com/documentation/publish-on-read-the-docs -.. _Level AA conformance: https://www.w3.org/WAI/WCAG2AA-Conformance -.. _list tables: https://docutils.sourceforge.io/docs/ref/rst/directives.html#list-table -.. _manual import: https://readthedocs.com/dashboard/import/manual/ -.. _Markdown: https://commonmark.org/ -.. _MyST: https://myst-parser.readthedocs.io/ -.. _Open Graph: https://ogp.me/ -.. _Pa11y: https://pa11y.org/ -.. _Pa11y readme: https://github.com/pa11y/pa11y#command-line-configuration -.. _Pygments documentation: https://pygments.org/languages/ -.. _Read the Docs at Canonical: https://library.canonical.com/documentation/read-the-docs-at-canonical -.. _reStructuredText: https://www.sphinx-doc.org/en/master/usage/restructuredtext/index.html -.. _`Sphinx`: https://www.sphinx-doc.org/ -.. _`Sphinx configuration`: https://www.sphinx-doc.org/en/master/usage/configuration.html -.. _Sphinx design: https://sphinx-design.readthedocs.io/en/latest/ -.. _Sphinx documentation starter pack: -.. _Sphinx documentation starter pack repository: https://github.com/canonical/starter-pack -.. _Sphinx documentation starter pack documentation: https://canonical-starter-pack.readthedocs-hosted.com/ -.. _`Sphinx extensions`: https://www.sphinx-doc.org/en/master/usage/extensions/index.html -.. _Sphinx tabs: https://sphinx-tabs.readthedocs.io/en/latest/ -.. _tables: https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html#table-directives -.. _toctree: https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html#directive-toctree -.. _Vale: https://vale.sh/ -.. _Vale rules: https://github.com/canonical/praecepta -.. _Web Content Accessibility Guidelines (WCAG) 2.2: https://www.w3.org/TR/WCAG22/ - - -.. SHORTCUTS -.. |RST| replace:: :abbr:`reST (reStructuredText)` diff --git a/docs/reuse/substitutions.txt b/docs/reuse/substitutions.txt deleted file mode 100644 index 307b5f2e..00000000 --- a/docs/reuse/substitutions.txt +++ /dev/null @@ -1,7 +0,0 @@ -.. |version_number| replace:: 0.1.0 - -.. |rest_text| replace:: *Multi-line* text - that uses basic **markup**. - -.. |site_link| replace:: Website link -.. _site_link: https://example.com \ No newline at end of file diff --git a/docs/reuse/substitutions.yaml b/docs/reuse/substitutions.yaml deleted file mode 100644 index 0c2958d2..00000000 --- a/docs/reuse/substitutions.yaml +++ /dev/null @@ -1,4 +0,0 @@ -# Key/value substitutions to use within the Sphinx doc. -{version_number: "0.1.0", - formatted_text: "*Multi-line* text\n that uses basic **markup**.", - site_link: "[Website link](https://example.com)"} \ No newline at end of file diff --git a/docs/snap/explanation/canonical-ceph-reference-architecture/architectural-considerations.rst b/docs/snap/explanation/canonical-ceph-reference-architecture/architectural-considerations.rst index bfa2f8e4..2a330017 100644 --- a/docs/snap/explanation/canonical-ceph-reference-architecture/architectural-considerations.rst +++ b/docs/snap/explanation/canonical-ceph-reference-architecture/architectural-considerations.rst @@ -32,7 +32,7 @@ Observability Stack (COS) `_, and for management/patching, we recommend using `Landscape `_. These typically require another three-node -cluster, which can be colocated with the Juju/MAAS infrastructure nodes where +cluster, which can be collocated with the Juju/MAAS infrastructure nodes where applicable, reducing the total infrastructure footprint. .. _cluster-service-placement: