diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 01d6b9f5b4c..ec26cd6741b 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -18,7 +18,7 @@ build: # This is a special exit code on Read the Docs that will cancel the build immediately. # https://docs.readthedocs.io/en/stable/build-customization.html#cancel-build-based-on-a-condition - | - if [ "$READTHEDOCS_VERSION_TYPE" = "external" ] && git diff --quiet origin/14/docs -- 'docs/' '.readthedocs.yaml'; + if [ "$READTHEDOCS_VERSION_TYPE" = "external" ] && git diff --quiet origin/main -- 'docs/' '.readthedocs.yaml'; then exit 183; fi @@ -30,8 +30,8 @@ sphinx: fail_on_warning: true # If using Sphinx, optionally build your docs in additional formats such as PDF -# formats: -# - pdf +formats: +- pdf # Optionally declare the Python requirements required to build your docs python: diff --git a/docs/.gitignore b/docs/.gitignore index aad78f1f7ce..46b29842caf 100644 --- a/docs/.gitignore +++ b/docs/.gitignore @@ -1,6 +1,6 @@ # Environment *env*/ -.sphinx/venv/ +.venv/ # Sphinx .sphinx/warnings.txt diff --git a/docs/.sphinx/.pymarkdown.json b/docs/.sphinx/.pymarkdown.json new file mode 100644 index 00000000000..2c4c669dbf8 --- /dev/null +++ b/docs/.sphinx/.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/.wordlist.txt b/docs/.sphinx/.wordlist.txt deleted file mode 100644 index fd1f10102ee..00000000000 --- a/docs/.sphinx/.wordlist.txt +++ /dev/null @@ -1,331 +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 diff --git a/docs/.sphinx/get_vale_conf.py b/docs/.sphinx/get_vale_conf.py old mode 100644 new mode 100755 index 46f57d89438..13e7966f86c --- a/docs/.sphinx/get_vale_conf.py +++ b/docs/.sphinx/get_vale_conf.py @@ -17,7 +17,7 @@ SPHINX_DIR = os.path.join(os.getcwd(), ".sphinx") -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 """ @@ -138,7 +138,7 @@ def main(): # 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/metrics/build_metrics.sh b/docs/.sphinx/metrics/build_metrics.sh deleted file mode 100755 index bd1ff1cb4c7..00000000000 --- 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 " str: - """Get SHA of local files""" - logging.debug(f"Getting hash of {os.path.basename(file)}") - return subprocess.check_output(["git", "hash-object", file]).decode("ascii").strip() - - -# Examines local files -def get_local_files_and_paths(): - """Identify '.sphinx' local files and paths""" - logging.debug("Checking local files and paths") - try: - files = [] - paths = [] - patterns = [".*", "**.*", "metrics/**.*"] - files, paths = [], [] - - for pattern in patterns: - for file in glob.iglob(os.path.join(SPHINX_DIR, pattern), recursive=True): - files.append(os.path.basename(file)) - paths.append(file) - return files, paths - except Exception as e: - logging.debug(e) - raise RuntimeError("get_local_files_and_paths()") from e - - -# General API query with timeout and RequestException -def query_api(url): - """Query an API with a globally set timeout""" - logging.debug(f"Querying {url}") - try: - r = requests.get(url, timeout=TIMEOUT) - return r - except RequestException as e: - raise RuntimeError(f"Failed query_api(): {url}") from e - - -# General file download function -def download_file(url, output_path): - """Download a file to a specified path""" - logging.debug(f"Downloading {os.path.basename(output_path)}") - try: - os.makedirs(os.path.dirname(output_path), exist_ok=True) - with open(output_path, "wb") as file: - file.write(query_api(url).content) - except Exception as e: - logging.debug(e) - raise RuntimeError(f"Failed download_file(): {url}") from e - - -if __name__ == "__main__": - sys.exit(main()) # Keep return code diff --git a/docs/.sphinx/version b/docs/.sphinx/version index 6d7de6e6abe..810ee4e91e2 100644 --- a/docs/.sphinx/version +++ b/docs/.sphinx/version @@ -1 +1 @@ -1.0.2 +1.6 diff --git a/docs/Makefile b/docs/Makefile index 18fb6a775cd..a4bb604cde3 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -4,22 +4,24 @@ # You can set these variables from the command line, and also # from the environment for the first two. -SPHINXDIR = .sphinx -SPHINXOPTS ?= -c . -d $(SPHINXDIR)/.doctrees -j auto -SPHINXBUILD ?= $(VENVDIR)/bin/sphinx-build -SOURCEDIR = . -BUILDDIR = _build -VENVDIR = $(SPHINXDIR)/venv -PA11Y = $(SPHINXDIR)/node_modules/pa11y/bin/pa11y.js --config $(SPHINXDIR)/pa11y.json -VENV = $(VENVDIR)/bin/activate -TARGET = * -ALLFILES = *.md **/*.md -METRICSDIR = $(SOURCEDIR)/.sphinx/metrics -REQPDFPACKS = latexmk fonts-freefont-otf texlive-latex-recommended texlive-latex-extra texlive-fonts-recommended texlive-font-utils texlive-lang-cjk texlive-xetex plantuml xindy tex-gyre dvipng -CONFIRM_SUDO ?= N -VALE_CONFIG = $(SPHINXDIR)/vale.ini -SPHINX_HOST ?= 127.0.0.1 -SPHINX_PORT ?= 8001 + +SPHINX_DIR ?= .sphinx +SPHINX_OPTS ?= -c . -d $(SPHINX_DIR)/.doctrees -j auto +SPHINX_BUILD ?= $(DOCS_VENVDIR)/bin/sphinx-build +SPHINX_HOST ?= 127.0.0.1 +SPHINX_PORT ?= 8000 +SPHINX_AUTOBUILD_OPTS ?= +DOCS_VENVDIR ?= .venv +DOCS_VENV ?= $(DOCS_VENVDIR)/bin/activate +DOCS_SOURCEDIR ?= . +DOCS_BUILDDIR ?= _build +DOCS_PDFPACKAGES ?= latexmk fonts-freefont-otf texlive-latex-recommended texlive-latex-extra texlive-fonts-recommended texlive-font-utils texlive-lang-cjk texlive-xetex plantuml xindy tex-gyre dvipng +DOCS_VOCAB ?= $(SPHINX_DIR)/styles/config/vocabularies/Canonical +VALE_DIR ?= $(DOCS_VENVDIR)/lib/python*/site-packages/vale +VALE_CONFIG ?= $(SPHINX_DIR)/vale.ini +PA11Y_CMD ?= $(SPHINX_DIR)/node_modules/pa11y/bin/pa11y.js --config $(SPHINX_DIR)/pa11y.json +CONFIRM_SUDO ?= N +CHECK_PATH ?= $(filter-out $(DOCS_VENVDIR),$(wildcard *)) # Put it first so that "make" without argument is like "make help". help: @@ -31,166 +33,160 @@ help: @echo "* clean built doc files: make clean-doc" @echo "* clean full environment: make clean" @echo "* check links: make linkcheck" + @echo "* check markdown: make lint-md" @echo "* check spelling: make spelling" @echo "* check spelling (without building again): make spellcheck" @echo "* check inclusive language: make woke" @echo "* check accessibility: make pa11y" @echo "* check style guide compliance: make vale" - @echo "* check style guide compliance on target: make vale TARGET=*" - @echo "* check metrics for documentation: make allmetrics" + @echo "* check style guide compliance on target: make vale CHECK_PATH=*" @echo "* other possible targets: make " @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 +.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 -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 $(SPHINX_DIR)/node_modules/ ; \ + npm install --prefix $(SPHINX_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) run: install - . $(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 - . $(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 $(SPHINX_DIR)/warnings.txt $(SPHINX_OPTS) epub: install - . $(VENV); $(SPHINXBUILD) -b epub "$(SOURCEDIR)" "$(BUILDDIR)" -w $(SPHINXDIR)/warnings.txt $(SPHINXOPTS) + . $(DOCS_VENV); $(SPHINX_BUILD) -b epub "$(DOCS_SOURCEDIR)" "$(DOCS_BUILDDIR)" -w $(SPHINX_DIR)/warnings.txt $(SPHINX_OPTS) serve: html - cd "$(BUILDDIR)"; python3 -m http.server --bind 127.0.0.1 8000 + 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 $(SPHINX_DIR)/node_modules/ + rm -rf $(SPHINX_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) - -spelling: html spellcheck + git clean -fx "$(DOCS_BUILDDIR)" + rm -rf $(SPHINX_DIR)/.doctrees linkcheck: install - . $(VENV) ; $(SPHINXBUILD) -b linkcheck "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) || { grep --color -F "[broken]" "$(BUILDDIR)/output.txt"; exit 1; } + . $(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 $(SPHINX_DIR)/.pymarkdown.json \ + --return-code-scheme explicit \ + scan \ + --recurse \ + --exclude=$(SPHINX_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 $(SPHINX_DIR)/get_vale_conf.py + @echo '.Name=="Canonical.400-Enforce-inclusive-terms"' > $(SPHINX_DIR)/styles/woke.filter + @echo '.Level=="error" and .Name!="Canonical.500-Repeated-words" and .Name!="Canonical.000-US-spellcheck"' > $(SPHINX_DIR)/styles/error.filter + @echo '.Name=="Canonical.000-US-spellcheck"' > $(SPHINX_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='$(SPHINX_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='$(SPHINX_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='$(SPHINX_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); .sphinx/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/_templates/footer.html b/docs/_templates/footer.html new file mode 100644 index 00000000000..f4ccfe04051 --- /dev/null +++ b/docs/_templates/footer.html @@ -0,0 +1,92 @@ + +
+
+ {%- if show_copyright %} + + {%- endif %} + + {# mod: removed "Made with" #} + + {%- if last_updated -%} +
+ {% trans last_updated=last_updated|e -%} + Last updated on {{ last_updated }} + {%- endtrans -%} +
+ {%- endif %} + + {%- if show_source and has_source and sourcename %} + + {%- endif %} +
+
+ {% if has_contributor_listing and display_contributors and pagename and page_source_suffix %} + {% set contributors = get_contributors_for_file(pagename, page_source_suffix) %} + {% if contributors %} + {% if contributors | length > 1 %} + Thanks to the {{ contributors |length }} contributors! + {% else %} + Thanks to our contributor! + {% endif %} +
+ + {% endif %} + {% endif %} +
+
Manage your tracker settings
+
\ No newline at end of file diff --git a/docs/_templates/header.html b/docs/_templates/header.html new file mode 100644 index 00000000000..9ee3c77d80b --- /dev/null +++ b/docs/_templates/header.html @@ -0,0 +1,72 @@ + \ No newline at end of file diff --git a/docs/conf.py b/docs/conf.py index 4c1e4fcbcd0..6ec1f4eba40 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,5 +1,4 @@ import datetime -import ast import os import yaml @@ -22,10 +21,19 @@ ####################### # Project name +# +# TODO: Update with the official name of your project or product project = "Charmed PostgreSQL" author = "Canonical Ltd." +# The year in the copyright statement defaults to the current year, so +# individual document versions show when they were built. +# TODO: If the date must be a range, like in a software license, replace +# 2026 with the starting year of development and use: +# + +copyright = f"2025-{datetime.date.today().year}" # Sidebar documentation title; best kept reasonably short # @@ -35,33 +43,6 @@ html_title = project + " 14 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. -# -# TODO: If your docs need another license, specify it instead of 'CC-BY-SA'. -# -# TODO: 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 CC-BY-SA, %s" % (datetime.date.today().year, author) - - # Documentation website URL # # TODO: Update with the official URL of your docs or leave empty if unsure. @@ -83,7 +64,7 @@ # # TODO: To customise the preview image, update as needed. -ogp_image = "https://assets.ubuntu.com/v1/253da317-image-document-ubuntudocs.svg" +ogp_image = "https://assets.ubuntu.com/v1/cc828679-docs_illustration.svg" # Product favicon; shown in bookmarks, browser tabs, etc. @@ -123,7 +104,7 @@ # Your Mattermost channel URL # # TODO: Change to your Mattermost channel URL or leave empty. - "mattermost": "", + # "mattermost": "", # Your Matrix channel URL # @@ -153,8 +134,35 @@ # Required for feedback button 'github_issues': 'enabled', + + # Inherit the author value + "author": author, + + # The starter pack uses CC-BY-SA as the license + # + # TODO: If your docs need another license, specify it instead of 'CC-BY-SA'. + # For the name, we recommend using the standard shorthand identifier from + # https://spdx.org/licenses + # + # For the URL, link directly to the license statement, typically found on + # the product's home page or in its GitHub project. + # + # TODO: 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'. + + "license": { + "name": "Apache License 2.0", + "url": "https://github.com/canonical/postgresql-operator/blob/main/LICENSE", + }, } +html_extra_path = [] + +# Allow opt-in build of the OpenAPI "Hello" example so docs stay clean by default. +# if os.getenv("OPENAPI", ""): +# tags.add("openapi") +# html_extra_path.append("how-to/assets/openapi.yaml") + # 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: @@ -173,30 +181,55 @@ # slug = '' +####################### +# Sitemap configuration: https://sphinx-sitemap.readthedocs.io/ +####################### + +# Use RTD canonical URL to ensure duplicate pages have a specific canonical URL -# Template and asset locations +html_baseurl = os.environ.get("READTHEDOCS_CANONICAL_URL", "/") -#html_static_path = ["_static"] -#templates_path = ["_templates"] +# sphinx-sitemap uses html_baseurl to generate the full URL for each page: +sitemap_url_scheme = '{link}' + +# Include `lastmod` dates in the sitemap: + +sitemap_show_lastmod = True + +# Exclude generated pages from the sitemap: + +sitemap_excludes = [ + '404/', + 'genindex/', + 'search/', +] + +# TODO: Add more pages to sitemap_excludes if needed. Wildcards are supported. +# For example, to exclude module pages generated by autodoc, add '_modules/*'. + +################################ +# 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. - -# redirects = {} - rediraffe_redirects = "redirects.txt" +# Strips '/index.html' from destination URLs when building with 'dirhtml' +rediraffe_dir_only = True + ########################### # Link checker exceptions # ########################### @@ -244,43 +277,48 @@ # https://www.sphinx-doc.org/en/master/usage/extensions/index.html # NOTE: The canonical_sphinx extension is required for the starter pack. -# It automatically enables the following extensions: -# - custom-rst-roles -# - myst_parser -# - notfound.extension -# - related-links -# - sphinx_copybutton -# - sphinx_design -# - sphinx_reredirects -# - sphinx_tabs.tabs -# - sphinxcontrib.jquery -# - 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_related_links", + "sphinx_roles", + "sphinx_terminal", + "sphinx_ubuntu_images", + "sphinx_youtube_links", "sphinxcontrib.cairosvgconverter", "sphinx_last_updated_by_git", "sphinx.ext.intersphinx", - "sphinxext.rediraffe" + "sphinx_sitemap", ] # Excludes files or directories from processing exclude_patterns = [ - "doc-cheat-sheet*", + ".venv*", ] # Adds custom CSS files, located under 'html_static_path' -# html_css_files = [] +html_css_files = [ + "https://assets.ubuntu.com/v1/d86746ef-cookie_banner.css", +] # Adds custom JavaScript files, located under 'html_static_path' -# html_js_files = [] - +html_js_files = [ + "https://assets.ubuntu.com/v1/287a5e8f-bundle.js", +] # Specifies a reST snippet to be appended to each .rst file diff --git a/docs/explanation/index.md b/docs/explanation/index.md index e84e4e5e84f..cabc6308697 100644 --- a/docs/explanation/index.md +++ b/docs/explanation/index.md @@ -3,18 +3,21 @@ Additional context about key concepts behind the PostgreSQL charm, including design and legacy information. -## Core concepts and design +## Core + +Core concepts about the history and high-level design of Charmed PostgreSQL: ```{toctree} :titlesonly: Architecture Interfaces and endpoints -Juju Charm versions ``` -## Operational concepts +## Operation + +Clarification of standard PostgreSQL operational concepts in the context of charms and Juju: ```{toctree} :titlesonly: @@ -24,9 +27,12 @@ Users Roles Logs Connection pooling +Juju ``` -## Security and hardening +## Security + +Overview of security features in the charm and hardening guidance: ```{toctree} :titlesonly: diff --git a/docs/how-to/index.md b/docs/how-to/index.md index 9ad709aea6d..81df3de69fc 100644 --- a/docs/how-to/index.md +++ b/docs/how-to/index.md @@ -1,3 +1,5 @@ + + (how-to)= # How-to guides @@ -5,128 +7,87 @@ The following guides cover key processes and common tasks for managing and using ## Deployment and setup -Installation of different cloud services with Juju: -* [Sunbeam] -* [MAAS] -* [AWS EC2] -* [GCE] -* [Azure] -* [Multi-availability zones (AZ)][Multi-AZ] - -Other deployment scenarios and configurations: -* [Terraform] -* [TLS VIP access] -* [Air-gapped] -* [Juju storage] - -## Usage and maintenance - -* [Integrate with another application] -* [External access] -* [Scale replicas] -* [Enable TLS] -* [Enable plugins/extensions] -* [Switchover/failover] - -## Backup and restore -* [Configure S3 AWS] -* [Configure S3 RadosGW] -* [Create a backup] -* [Restore a backup] -* [Manage backup retention] -* [Migrate a cluster] - -## Monitoring (COS) - -* [Enable monitoring] with Grafana -* [Enable alert rules] with Prometheus -* [Enable tracing] with Tempo -* [Enable profiling] with Parca - -## Minor upgrades -* [Perform a minor upgrade] -* [Perform a minor rollback] - -## Cross-regional (cluster-cluster) async replication - -* [Cross-regional async replication] - * [Set up clusters] - * [Integrate with a client app] - * [Remove or recover a cluster] - * [Enable plugins/extensions] - -## Development - -This section is for charm developers looking to support PostgreSQL integrations with their charm. - -* [Integrate with your charm] -* [Migrate data via pg_dump] -* [Migrate data via backup/restore] - - - -[Sunbeam]: /how-to/deploy/sunbeam -[MAAS]: /how-to/deploy/maas -[AWS EC2]: /how-to/deploy/aws-ec2 -[GCE]: /how-to/deploy/gce -[Azure]: /how-to/deploy/azure -[Multi-AZ]: /how-to/deploy/multi-az -[TLS VIP access]: /how-to/deploy/tls-vip-access -[Juju spaces]: /how-to/deploy/juju-spaces -[Terraform]: /how-to/deploy/terraform -[Air-gapped]: /how-to/deploy/air-gapped -[Juju storage]: /how-to/deploy/juju-storage - -[Integrate with another application]: /how-to/integrate-with-another-application -[External access]: /how-to/external-network-access -[Scale replicas]: /how-to/scale-replicas -[Enable TLS]: /how-to/enable-tls -[Switchover/failover]: /how-to/switchover-failover - -[Configure S3 AWS]: /how-to/back-up-and-restore/configure-s3-aws -[Configure S3 RadosGW]: /how-to/back-up-and-restore/configure-s3-radosgw -[Create a backup]: /how-to/back-up-and-restore/create-a-backup -[Restore a backup]: /how-to/back-up-and-restore/restore-a-backup -[Manage backup retention]: /how-to/back-up-and-restore/manage-backup-retention -[Migrate a cluster]: /how-to/back-up-and-restore/migrate-a-cluster - -[Enable monitoring]: /how-to/monitoring-cos/enable-monitoring -[Enable alert rules]: /how-to/monitoring-cos/enable-alert-rules -[Enable tracing]: /how-to/monitoring-cos/enable-tracing -[Enable profiling]: /how-to/monitoring-cos/enable-profiling - -[Perform a minor upgrade]: /how-to/upgrade/perform-a-minor-upgrade -[Perform a minor rollback]: /how-to/upgrade/perform-a-minor-rollback - -[Cross-regional async replication]: /how-to/cross-regional-async-replication/index -[Set up clusters]: /how-to/cross-regional-async-replication/set-up-clusters -[Integrate with a client app]: /how-to/cross-regional-async-replication/integrate-with-a-client-app -[Remove or recover a cluster]: /how-to/cross-regional-async-replication/remove-or-recover-a-cluster -[Enable plugins/extensions]: /how-to/enable-plugins-extensions/index - -[Integrate with your charm]: /how-to/development/integrate-with-your-charm -[Migrate data via pg_dump]: /how-to/development/migrate-data-via-pg-dump -[Migrate data via backup/restore]: /how-to/development/migrate-data-via-backup-restore - +Available deployment methods, clouds, and specialised setups: ```{toctree} :titlesonly: :maxdepth: 2 -:glob: -:hidden: Deploy +``` + +## Operations and maintenance + +Essential operations to configure and manage a PostgreSQL cluster: + +```{toctree} +:titlesonly: + +Scale Integrate Manage passwords -External network access -Scale -Switchover/failover Enable TLS -Enable LDAP Enable plugins/extensions +``` + +Advanced networking, credential management, and disaster recovery: + +```{toctree} +:titlesonly: + +External network access +Enable LDAP +Switchover/failover +``` + +### Backups and data migration + +Configuration of storage providers and backup management: + +```{toctree} +:titlesonly: +:maxdepth: 2 + Back up and restore +``` + +### Monitoring (COS) + +Set up observability services like Grafana, Prometheus, Loki, and Tempo through the Canonical Observability Stack (COS): + +```{toctree} +:maxdepth: 2 + Monitoring (COS) -Upgrade +``` + +### Refresh (upgrade) + +Instructions for performing an in-place application refresh: + +```{toctree} +:titlesonly: + +Refresh (upgrade) +``` + +### Cross-regional (cluster-cluster) async replication + +Walkthrough of a cluster-cluster deployment and its essential operations: + +```{toctree} +:titlesonly: +:maxdepth: 2 + Cross-regional async replication -Development ``` + +## Charm development + +For charm developers looking to support PostgreSQL integrations with their charm + +```{toctree} +:titlesonly: + +Development +``` \ No newline at end of file diff --git a/docs/index.md b/docs/index.md index 12324a925f4..119c5605171 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,8 +1,8 @@ # Charmed PostgreSQL documentation -Charmed PostgreSQL is an open-source software operator designed to deploy and operate object-relational databases on IAAS/VM. It packages the powerful database management system [PostgreSQL](https://www.postgresql.org/) into a charmed operator for deployment with [Juju](https://juju.is/docs/juju). +Charmed PostgreSQL is an open-source operator designed to deploy and operate PostgreSQL on virtual machines and cloud services. It packages the relational database management system [PostgreSQL](https://www.postgresql.org/) with the [Patroni](https://patroni.readthedocs.io/en/latest/) high-availability replication system into an operator for deployment with [Juju](https://juju.is/docs/juju). -This charmed operator meets the need of simplifying deployment, scaling, configuration and management of relational databases in large-scale production environments reliably. It is equipped with several features to securely store and scale complicated data workloads, including easy integration with client applications. +This charmed operator simplifies deployment, scaling, configuration and management of PostgreSQL databases in large-scale production environments reliably. It is equipped with several features to securely store and scale complicated data workloads, including easy integration with client applications. Charmed PostgreSQL is made for anyone looking for a comprehensive database management interface, whether for operating a complex production environment or simply as a playground to learn more about databases and charms. @@ -10,32 +10,61 @@ Charmed PostgreSQL is made for anyone looking for a comprehensive database manag This is a **IAAS/VM** operator. To deploy on Kubernetes, see [Charmed PostgreSQL K8s](https://canonical-charmed-postgresql-k8s.readthedocs-hosted.com/). ``` -| | | -|--|--| -| [**Get started**](/tutorial/index) - [Deploy on a cloud](/how-to/deploy/index) \| [Scale](/how-to/scale-replicas) \| [Manage passwords](/how-to/manage-passwords) \| [Enable encryption](/how-to/enable-tls) \| [Back up](/how-to/back-up-and-restore/index) \| [Monitoring](/how-to/monitoring-cos/index)
| [**How-to guides**](/how-to/index) for key tasks, use-cases, and problems. These guides assume basic familiarity with Juju and PostgreSQL.
| -| [**Reference**](/reference/index) - Technical information for quick lookup, such as [requirements](/reference/system-requirements), [plugins](/reference/plugins-extensions), and [statuses](/reference/statuses). | [**Explanation**](/explanation/interfaces-and-endpoints) - Discussion and clarification of key topics such as [architecture](/explanation/architecture), [users](/explanation/users), and [charm versions](/explanation/charm-versions/index)| +## In this documentation +### Get started + +Learn about what's in the charm, how to set up your environment, and perform the most common operations. + +* **Charm overview**: {ref}`system-requirements` • {ref}`architecture` +* **Deploy PostgreSQL**: {ref}`Guided tutorial ` • {ref}`Quickstart ` +* **Key operations**: {ref}`Scale your cluster ` • {ref}`Connect to a client ` • {ref}`Create a backup ` + +### Production deployments + +Advanced deployments and operations focused on production scenarios and high availability. + +* **Advanced deployment scenarios**: {ref}`Terraform ` • {ref}`Air-gapped deployments ` • {ref}`Multiple availability zones ` • {ref}`Cluster-cluster replication ` +* **Networking**: {ref}`Enable TLS encryption ` • {ref}`External network access ` +* **Upgrades and data migration**: {ref}`In-place refresh (upgrade) ` • {ref}`Cluster migration ` +* **Troubleshooting**: {ref}`Overview and tools ` • {ref}`Manual switchover/failover ` • {ref}`Logs` • {ref}`sos-report` + +### Charm developers + +Information for developers looking to make their application compatible with PostgreSQL. + +* **Charm integrations**: {ref}`Interfaces and endpoints ` • {ref}`How to integrate with your charm with PostgreSQL ` +* **Learn about the PostgreSQL charm's design**: {ref}`architecture` • {ref}`Internal users ` • {ref}`Roles ` • {ref}`Charm versions ` +* **Juju properties**: [Configuration parameters](https://charmhub.io/postgresql/configurations?channel=14/stable) • [Actions](https://charmhub.io/postgresql/actions?channel=14/stable) + +## How this documentation is organised + +This documentation uses the [Diátaxis documentation structure](https://diataxis.fr/): + +* The {ref}`tutorial` provides step-by-step guidance for a beginner through the basics of a deployment in a local machine. +* {ref}`how-to` are more focused, and assume you already have basic familiarity with the product. +* {ref}`reference` contains structured information for quick lookup, such as system requirements and configuration parameters +* {ref}`explanation` gives more background and context about key topics ## Project and community Charmed PostgreSQL is an official distribution of PostgreSQL. It’s an open-source project that welcomes community contributions, suggestions, fixes and constructive feedback. -- [Read our Code of Conduct](https://ubuntu.com/community/code-of-conduct) -- [Join the Discourse forum](https://discourse.charmhub.io/tag/postgresql) -- [Contribute](https://github.com/canonical/postgresql-operator/blob/main/CONTRIBUTING.md) to the code or report an [issue](https://github.com/canonical/postgresql-operator/issues/new/choose) -- Explore [Canonical Data solutions](https://canonical.com/data) -- [Contacts us](/reference/contacts) for all further questions -## Licensing & Trademark +### Get involved + +* [Discourse forum](https://discourse.charmhub.io/tag/postgresql) +* [Public Matrix channel](https://matrix.to/#/#charmhub-data-platform:ubuntu.com) +* [Report an issue](https://github.com/canonical/postgresql-operator/issues/new/choose) +* [Contribute](https://github.com/canonical/postgresql-operator/blob/main/CONTRIBUTING.md) -The Charmed PostgreSQL Operator is distributed under the [Apache Software Licence version 2.0](https://github.com/canonical/postgresql-operator/blob/main/LICENSE). It depends on [PostgreSQL](https://www.postgresql.org/ftp/source/), which is licensed under the [PostgreSQL License](https://www.postgresql.org/about/licence/) - a liberal open-source licence similar to the BSD or MIT licences. +### Governance and policies -PostgreSQL is a trademark or registered trademark of PostgreSQL Global Development Group. Other trademarks are the property of their respective owners. +- [Code of Conduct](https://ubuntu.com/community/code-of-conduct) ```{toctree} :titlesonly: :maxdepth: 2 -:glob: :hidden: Home diff --git a/docs/reference/alert-rules.md b/docs/reference/alert-rules.md index 25a4769a8f9..4146ae55e66 100644 --- a/docs/reference/alert-rules.md +++ b/docs/reference/alert-rules.md @@ -20,7 +20,7 @@ This page contains a markdown version of the alert rules described in the `postg | PostgresqlTooManyConnections | ![warning] | PostgresSQL instance is using > 80% of the maximum connections.
Consider checking how many connections the client application is opening, or using PgBouncer in front of the database. | | PostgresqlNotEnoughConnections | ![info] | PostgresSQL instance does not have enough connections.
PostgreSQL instance should have more connections (> 5).
Consider double-checking how many connections the client application is opening and/or using PgBouncer in front of the database. | | PostgresqlDeadLocks | ![warning] | PostgresSQL instance has dead locks.
See more details with the pg_locks view. | -| PostgresqlHighRollbackRate | ![warning] | PostgresSQL instance has a high rollback rate instance.
The ratio of transactions being aborted compared to committed is > 2 %.
This is probably happening due to unoptimised configurations related to commit delay, connections, memory, and WAL files. | +| PostgresqlHighRollbackRate | ![warning] | PostgresSQL instance has a high rollback rate instance.
The ratio of transactions being aborted compared to committed is > 2 %.
This is probably happening due to non-optimal configurations related to commit delay, connections, memory, and WAL files. | | PostgresqlCommitRateLow | ![info] | PostgresSQL instance has a low commit rate.
PostgresSQL seems to be processing very few transactions.
Check for long-running queries and configuration issues, like insufficient cache size. | | PostgresqlLowXidConsumption | ![info] | PostgresSQL instance shows low XID consumption.
PostgresSQL seems to be consuming transaction IDs very slowly.
Run ANALYZE to update the optimizer statistics, ensure that query plans are correct, and double-check your VACUUM settings. | | PostgresqlHighRateStatementTimeout | ![critical] | PostgresSQL instance shows a high rate of statement timeout.
Either tune `statement_timeout` when sending queries or use EXPLAIN ANALYZE to understand how the queries can be improved. | @@ -58,8 +58,8 @@ This page contains a markdown version of the alert rules described in the `postg | `PgBackRestBackupError` | ![critical] | Backup failed for a stanza.
The last pgBackRest backup ended with error status > 0.
Check the pgBackRest logs for the stanza. | | `PgBackRestBackupTooOld` | ![warning] | No recent backup available.
The last pgBackRest backup is older than 7 days.
Consider checking your backup schedule, capacity, and logs. | | `PgBackRestStanzaError` | ![warning] | A stanza has reported errors.
Status > 0 indicates problems such as missing stanza path or no valid backups.
Check pgBackRest logs for details. | -| `PgBackRestRepoError` | ![warning] | A repository has reported errors.
Status > 0 indicates the repo may be inaccessible, out of space, or otherwise unhealthy.
Check pgBackRest logs and storage system. | -| `PgBackRestExporterError` | ![critical] | The pgBackRest exporter failed to fetch data.
Metric `pgbackrest_exporter_status == 0` indicates exporter-side issues.
This may be a misconfiguration or runtime error; check exporter logs. | +| `PgBackRestRepoError` | ![warning] | A repository has reported errors.
Status > 0 indicates the repository may be inaccessible, out of space, or otherwise unhealthy.
Check pgBackRest logs and storage system. | +| `PgBackRestExporterError` | ![critical] | The pgBackRest exporter failed to fetch data.
Metric `pgbackrest_exporter_status == 0` indicates exporter-side issues.
This may be an incorrect configuration or a runtime error. Check exporter logs. | [info]: https://img.shields.io/badge/info-blue diff --git a/docs/reference/index.md b/docs/reference/index.md index 6128700811a..834349dc046 100644 --- a/docs/reference/index.md +++ b/docs/reference/index.md @@ -1,29 +1,45 @@ (reference)= # Reference -The following generated API references can be found on [Charmhub](https://charmhub.io/postgresql): +Information about releases, charm options, technical specifications, and other reference material for quick lookup. -| Page | Description | -|------|-------------| -| [Integrations](https://charmhub.io/postgresql/integrations) | Integration/relation interfaces supported by this charm | -| [Libraries](https://charmhub.io/postgresql/libraries) | VM charm library is empty as charm uses [K8s library](https://charmhub.io/postgresql-k8s/libraries/) (more info [here](/explanation/architecture)) | -| [Configuration](https://charmhub.io/postgresql/configuration) | Application configuration parameters | -| [Actions](https://charmhub.io/postgresql/actions) | Juju actions supported by this charm | - -The following guides contain technical specifications, APIs, release notes, and other reference material for fast lookup. +## Releases +All stable revisions of Charmed PostgreSQL 14 for bare metal/virtual machines: ```{toctree} :titlesonly: -:maxdepth: 2 -:glob: Releases +``` + +## Requirements and operations + +Technical specifications, performance guidance, software testing approaches, and troubleshooting resources. + +```{toctree} +:titlesonly: + System requirements -Software testing Performance and resources Troubleshooting +Charm statuses +``` + +## Integrations + +Available plugins and extensions, Prometheus alert rules, and testing information. + +```{toctree} +:titlesonly: + Plugins/extensions Alert rules -Statuses +Software testing +``` + +```{toctree} +:hidden: + Contacts +``` \ No newline at end of file diff --git a/docs/reference/system-requirements.md b/docs/reference/system-requirements.md index e8b24994e00..905abe5164f 100644 --- a/docs/reference/system-requirements.md +++ b/docs/reference/system-requirements.md @@ -8,7 +8,7 @@ The following are the minimum software and hardware requirements to run Charmed ### Juju -The charm supports several Juju releases from [2.9 LTS](https://documentation.ubuntu.com/juju/3.6/releasenotes/juju_2.9.x/) onwards. The table below shows which minor versions of each major Juju release are supported by the stable Charmhub releases of PostgreSQL. +The charm supports several Juju releases from [2.9 LTS](https://documentation.ubuntu.com/juju/3.6/releasenotes/juju_2.9.x/) onward. The table below shows which minor versions of each major Juju release are supported by the stable Charmhub releases of PostgreSQL. | Juju major release | Supported minor versions | Compatible charm revisions |Comment | |:--------|:-----|:-----|:-----| diff --git a/docs/requirements.txt b/docs/requirements.txt index 769442aef60..550b26c82a3 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,4 +1,33 @@ -canonical-sphinx[full] +# 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 +sphinx-notfound-page +sphinx-reredirects +sphinx-tabs +sphinxcontrib-jquery +sphinxext-opengraph +sphinx-rerediraffe + +# Extra extensions, previously bundled as canonical-sphinx-extensions +sphinx-config-options>=0.1.0 +sphinx-contributor-listing>=0.1.0 +sphinx-filtered-toctree>=0.1.0 +sphinx-related-links>=0.1.2 +sphinx-roles>=0.1.0 +sphinx-terminal>=1.0.2 +sphinx-ubuntu-images>=0.1.0 +sphinx-youtube-links>=0.1.0 + +# Other dependencies +packaging sphinxcontrib-svg2pdfconverter[CairoSVG] sphinx-last-updated-by-git -sphinxext-rediraffe \ No newline at end of file +sphinx-sitemap + +# Vale dependencies +rst2html +vale \ No newline at end of file