From 31cdc508646aece961f59a30e8c1a315d6e0c3f2 Mon Sep 17 00:00:00 2001 From: David Wilding Date: Tue, 23 Dec 2025 10:14:55 +0800 Subject: [PATCH 01/16] update Makefile --- docs/Makefile | 51 ++++++++++++++++++++++++++------------------------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/docs/Makefile b/docs/Makefile index 049890790..13b007bfc 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -7,17 +7,18 @@ SPHINXDIR = .sphinx SPHINXOPTS ?= -c . -d $(SPHINXDIR)/.doctrees -j auto SPHINXBUILD ?= $(VENVDIR)/bin/sphinx-build -SOURCEDIR = . +SOURCEDIR ?= . BUILDDIR = _build -VENVDIR = $(SPHINXDIR)/venv +VENVDIR ?= $(SPHINXDIR)/venv PA11Y = $(SPHINXDIR)/node_modules/pa11y/bin/pa11y.js --config $(SPHINXDIR)/pa11y.json VENV = $(VENVDIR)/bin/activate TARGET = * -ALLFILES = *.rst **/*.rst 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 +VALEDIR = $(SPHINXDIR)/venv/lib/python*/site-packages/vale +VOCAB_CANONICAL = $(SPHINXDIR)/styles/config/vocabularies/Canonical SPHINX_HOST ?= 127.0.0.1 SPHINX_PORT ?= 8000 @@ -44,10 +45,10 @@ help: @echo "-------------------------------------------------------------" @echo -.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 allmetrics \ - update lint-md +.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 allmetrics \ + update lint-md cli-help full-help: $(VENVDIR) @. $(VENV); $(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) @@ -89,7 +90,7 @@ epub: install . $(VENV); $(SPHINXBUILD) -b epub "$(SOURCEDIR)" "$(BUILDDIR)" -w $(SPHINXDIR)/warnings.txt $(SPHINXOPTS) serve: html - cd "$(BUILDDIR)"; python3 -m http.server --bind 127.0.0.1 8000 + cd "$(BUILDDIR)"; python3 -m http.server --bind $(SPHINX_HOST) $(SPHINX_PORT) clean: clean-doc @test ! -e "$(VENVDIR)" -o -d "$(VENVDIR)" -a "$(abspath $(VENVDIR))" != "$(VENVDIR)" @@ -117,28 +118,28 @@ vale-install: install @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 \; + @. $(VENV); find $(VALEDIR)/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 $(SOURCEDIR)/.custom_wordlist.txt >> $(SPHINXDIR)/styles/config/vocabularies/Canonical/accept.txt + @cat $(VOCAB_CANONICAL)/accept.txt > $(VOCAB_CANONICAL)/accept_backup.txt + @cat $(SOURCEDIR)/.custom_wordlist.txt >> $(VOCAB_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 $(VOCAB_CANONICAL)/accept_backup.txt > $(VOCAB_CANONICAL)/accept.txt && rm $(VOCAB_CANONICAL)/accept_backup.txt vale: vale-install - @cat $(SPHINXDIR)/styles/config/vocabularies/Canonical/accept.txt > $(SPHINXDIR)/styles/config/vocabularies/Canonical/accept_backup.txt - @cat $(SOURCEDIR)/.custom_wordlist.txt >> $(SPHINXDIR)/styles/config/vocabularies/Canonical/accept.txt + @cat $(VOCAB_CANONICAL)/accept.txt > $(VOCAB_CANONICAL)/accept_backup.txt + @cat $(SOURCEDIR)/.custom_wordlist.txt >> $(VOCAB_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 + @cat $(VOCAB_CANONICAL)/accept_backup.txt > $(VOCAB_CANONICAL)/accept.txt && rm $(VOCAB_CANONICAL)/accept_backup.txt spelling: vale-install - @cat $(SPHINXDIR)/styles/config/vocabularies/Canonical/accept.txt > $(SPHINXDIR)/styles/config/vocabularies/Canonical/accept_backup.txt - @cat $(SOURCEDIR)/.custom_wordlist.txt >> $(SPHINXDIR)/styles/config/vocabularies/Canonical/accept.txt + @cat $(VOCAB_CANONICAL)/accept.txt > $(VOCAB_CANONICAL)/accept_backup.txt + @cat $(SOURCEDIR)/.custom_wordlist.txt >> $(VOCAB_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 $(VOCAB_CANONICAL)/accept_backup.txt > $(VOCAB_CANONICAL)/accept.txt && rm $(VOCAB_CANONICAL)/accept_backup.txt spellcheck: spelling @echo "Please note that the \`make spellcheck\` command is being deprecated in favor of \`make spelling\`" @@ -169,21 +170,21 @@ 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 -d $(VALEDIR) || 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 \; + @. $(VENV); find $(VALEDIR)/vale_bin -size 195c -exec vale --config "$(VALE_CONFIG)" $(TARGET) > /dev/null \; @eval '$(METRICSDIR)/source_metrics.sh $(PWD)' - @$(METRICSDIR)/build_metrics.py $(BUILDDIR) + @. $(VENV); python3 $(METRICSDIR)/build_metrics.py $(BUILDDIR) update: install @. $(VENV); .sphinx/update_sp.py +cli-help: + @echo "Regenerating help output in CLI reference..." + @python3 generate_command_docs.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) --no-print-directory install . $(VENV); $(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -cli-help: - @echo "Regenerating help output in CLI reference..." - @python3 generate_command_docs.py From 4c40eda3f6975f2f273523d0f4f36e7d2e59884b Mon Sep 17 00:00:00 2001 From: David Wilding Date: Tue, 23 Dec 2025 10:15:40 +0800 Subject: [PATCH 02/16] update the update script --- docs/.sphinx/update_sp.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/docs/.sphinx/update_sp.py b/docs/.sphinx/update_sp.py index 44c10d9bb..576cfcd21 100755 --- a/docs/.sphinx/update_sp.py +++ b/docs/.sphinx/update_sp.py @@ -18,12 +18,14 @@ from requests.exceptions import RequestException from packaging.version import parse as parse_version -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_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_RAW_BASE = f"https://raw.githubusercontent.com/{GITHUB_REPO}/main" TIMEOUT = 10 # seconds @@ -103,7 +105,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 +115,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,7 +123,7 @@ 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") @@ -206,7 +208,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") From a6b7a96196c1c9d88857ec49c837a0265dbe46c7 Mon Sep 17 00:00:00 2001 From: David Wilding Date: Tue, 23 Dec 2025 10:18:04 +0800 Subject: [PATCH 03/16] update metrics script --- docs/.sphinx/metrics/build_metrics.py | 94 +++++++++++++++++++++++++++ docs/.sphinx/metrics/build_metrics.sh | 15 ----- 2 files changed, 94 insertions(+), 15 deletions(-) create mode 100755 docs/.sphinx/metrics/build_metrics.py delete mode 100755 docs/.sphinx/metrics/build_metrics.sh diff --git a/docs/.sphinx/metrics/build_metrics.py b/docs/.sphinx/metrics/build_metrics.py new file mode 100755 index 000000000..529fb85b9 --- /dev/null +++ b/docs/.sphinx/metrics/build_metrics.py @@ -0,0 +1,94 @@ +#!/usr/bin/python3 + +import sys +import argparse +from pathlib import Path +from html.parser import HTMLParser +from urllib.parse import urlsplit + + +class MetricsParser(HTMLParser): + def __init__(self): + super().__init__() + self.int_link_count = 0 + self.ext_link_count = 0 + self.fragment_count = 0 + self.image_count = 0 + self.in_object = 0 + + @property + def link_count(self): + return self.fragment_count + self.int_link_count + self.ext_link_count + + def read(self, file): + """ + Read *file* (a file-like object with a ``read`` method returning + strings) a chunk at a time, feeding each chunk to the parser. + """ + # Ensure the parser state is reset before each file (just in case + # there's an erroneous dangling ) + self.reset() + self.in_object = 0 + buf = '' + while True: + # Parse 1MB chunks at a time + buf = file.read(1024**2) + if not buf: + break + self.feed(buf) + + def handle_starttag(self, tag, attrs): + """ + Count , , and tags to determine the number of internal + and external links, and the number of images. + """ + attrs = dict(attrs) + if tag == 'a' and 'href' in attrs: + # If there's no href, it's an anchor; if there's no hostname + # (netloc) or path, it's just a fragment link within the page + url = urlsplit(attrs['href']) + if url.netloc: + self.ext_link_count += 1 + elif url.path: + self.int_link_count += 1 + else: + self.fragment_count += 1 + elif tag == 'object': + # tags are a bit complex as they nest to offer fallbacks + # and may contain an fallback. We only want to count the + # outer-most in this case + if self.in_object == 0: + self.image_count += 1 + self.in_object += 1 + elif tag == 'img' and self.in_object == 0: + self.image_count += 1 + + def handle_endtag(self, tag): + if tag == 'object': + # Never let in_object be negative + self.in_object = max(0, self.in_object - 1) + + +def main(args=None): + parser = argparse.ArgumentParser() + parser.add_argument( + 'build_dir', metavar='build-dir', nargs='?', default='.', + help="The directory to scan for HTML files") + config = parser.parse_args(args) + + parser = MetricsParser() + for path in Path(config.build_dir).rglob('*.html'): + with path.open('r', encoding='utf-8', errors='replace') as f: + parser.read(f) + + print('Summarising metrics for build files (.html)...') + print(f'\tlinks: {parser.link_count} (' + f'{parser.fragment_count} #frag…, ' + f'{parser.int_link_count} /int…, ' + f'{parser.ext_link_count} https://ext…' + ')') + print(f'\timages: {parser.image_count}') + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/docs/.sphinx/metrics/build_metrics.sh b/docs/.sphinx/metrics/build_metrics.sh deleted file mode 100755 index bd1ff1cb4..000000000 --- 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 " Date: Tue, 23 Dec 2025 10:19:27 +0800 Subject: [PATCH 04/16] update starter pack version file --- docs/.sphinx/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/.sphinx/version b/docs/.sphinx/version index b61022820..3a3cd8cc8 100644 --- a/docs/.sphinx/version +++ b/docs/.sphinx/version @@ -1 +1 @@ -1.1.0+preview +1.3.1 From b29c8feb138670920b99aa211e4f1b9406749160 Mon Sep 17 00:00:00 2001 From: David Wilding Date: Tue, 23 Dec 2025 10:25:18 +0800 Subject: [PATCH 05/16] update base URL and sitemap URLs --- docs/conf.py | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 1ae73dd53..b882bada6 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -64,13 +64,26 @@ copyright = "%s, %s" % (datetime.date.today().year, author) -# Documentation website URL and sitemap -# -# NOTE: 'html_baseurl' and 'sitemap_url_scheme' are used by the sphinx_sitemap -# extension. See https://sphinx-sitemap.readthedocs.io/ +# Use RTD canonical URL to ensure duplicate pages have a specific canonical URL + +html_baseurl = os.environ.get("READTHEDOCS_CANONICAL_URL", "/") + +# 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/', +] -html_baseurl = "https://documentation.ubuntu.com/pebble/" -sitemap_url_scheme = "{link}" # TODO: Update with the official URL of your docs or leave empty if unsure. # From 857d1582433c44a8a41e6861d58074d8adff29e0 Mon Sep 17 00:00:00 2001 From: David Wilding Date: Tue, 23 Dec 2025 10:25:51 +0800 Subject: [PATCH 06/16] update ogp_image --- docs/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index b882bada6..b3950709e 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -104,7 +104,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. From baac491c8cbb9c8df98ce2128df09e9404f32909 Mon Sep 17 00:00:00 2001 From: David Wilding Date: Tue, 23 Dec 2025 10:33:12 +0800 Subject: [PATCH 07/16] update vale config for new spellcheck --- docs/.sphinx/get_vale_conf.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/.sphinx/get_vale_conf.py b/docs/.sphinx/get_vale_conf.py index 46f57d894..13e7966f8 100644 --- 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 From 65dab72f947b944fb4100ab14f3de957caa014ed Mon Sep 17 00:00:00 2001 From: David Wilding Date: Tue, 23 Dec 2025 10:33:25 +0800 Subject: [PATCH 08/16] remove starter pack files we don't use --- docs/.sphinx/.markdownlint.json | 21 -- docs/.sphinx/.pre-commit-config.yaml | 23 -- docs/.sphinx/.wordlist.txt | 329 ------------------------- docs/.sphinx/metrics/build_metrics.py | 94 ------- docs/.sphinx/metrics/source_metrics.sh | 66 ----- docs/.sphinx/pa11y.json | 9 - docs/.sphinx/spellingcheck.yaml | 30 --- 7 files changed, 572 deletions(-) delete mode 100644 docs/.sphinx/.markdownlint.json delete mode 100644 docs/.sphinx/.pre-commit-config.yaml delete mode 100644 docs/.sphinx/.wordlist.txt delete mode 100755 docs/.sphinx/metrics/build_metrics.py delete mode 100755 docs/.sphinx/metrics/source_metrics.sh delete mode 100644 docs/.sphinx/pa11y.json delete mode 100644 docs/.sphinx/spellingcheck.yaml diff --git a/docs/.sphinx/.markdownlint.json b/docs/.sphinx/.markdownlint.json deleted file mode 100644 index 536f9ea92..000000000 --- a/docs/.sphinx/.markdownlint.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "default": false, - "MD003": { - "style": "atx" - }, - "MD014": true, - "MD018": true, - "MD022": true, - "MD023": true, - "MD026": { - "punctuation": ".,;。,;" - }, - "MD031": { - "list_items": false - }, - "MD032": true, - "MD035": true, - "MD042": true, - "MD045": true, - "MD052": true -} \ No newline at end of file diff --git a/docs/.sphinx/.pre-commit-config.yaml b/docs/.sphinx/.pre-commit-config.yaml deleted file mode 100644 index 07e0b48cb..000000000 --- a/docs/.sphinx/.pre-commit-config.yaml +++ /dev/null @@ -1,23 +0,0 @@ -repos: - - repo: local - hooks: - - id: make-spelling - name: Run make spelling - entry: make -C docs spelling - language: system - pass_filenames: false - files: ^docs/.*\.(rst|md|txt)$ - - - id: make-linkcheck - name: Run make linkcheck - entry: make -C docs linkcheck - language: system - pass_filenames: false - files: ^docs/.*\.(rst|md|txt)$ - - - id: make-woke - name: Run make woke - entry: make -C docs woke - language: system - pass_filenames: false - files: ^docs/.*\.(rst|md|txt)$ diff --git a/docs/.sphinx/.wordlist.txt b/docs/.sphinx/.wordlist.txt deleted file mode 100644 index 32bcd7c0b..000000000 --- a/docs/.sphinx/.wordlist.txt +++ /dev/null @@ -1,329 +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 -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/metrics/build_metrics.py b/docs/.sphinx/metrics/build_metrics.py deleted file mode 100755 index 529fb85b9..000000000 --- a/docs/.sphinx/metrics/build_metrics.py +++ /dev/null @@ -1,94 +0,0 @@ -#!/usr/bin/python3 - -import sys -import argparse -from pathlib import Path -from html.parser import HTMLParser -from urllib.parse import urlsplit - - -class MetricsParser(HTMLParser): - def __init__(self): - super().__init__() - self.int_link_count = 0 - self.ext_link_count = 0 - self.fragment_count = 0 - self.image_count = 0 - self.in_object = 0 - - @property - def link_count(self): - return self.fragment_count + self.int_link_count + self.ext_link_count - - def read(self, file): - """ - Read *file* (a file-like object with a ``read`` method returning - strings) a chunk at a time, feeding each chunk to the parser. - """ - # Ensure the parser state is reset before each file (just in case - # there's an erroneous dangling ) - self.reset() - self.in_object = 0 - buf = '' - while True: - # Parse 1MB chunks at a time - buf = file.read(1024**2) - if not buf: - break - self.feed(buf) - - def handle_starttag(self, tag, attrs): - """ - Count , , and tags to determine the number of internal - and external links, and the number of images. - """ - attrs = dict(attrs) - if tag == 'a' and 'href' in attrs: - # If there's no href, it's an anchor; if there's no hostname - # (netloc) or path, it's just a fragment link within the page - url = urlsplit(attrs['href']) - if url.netloc: - self.ext_link_count += 1 - elif url.path: - self.int_link_count += 1 - else: - self.fragment_count += 1 - elif tag == 'object': - # tags are a bit complex as they nest to offer fallbacks - # and may contain an fallback. We only want to count the - # outer-most in this case - if self.in_object == 0: - self.image_count += 1 - self.in_object += 1 - elif tag == 'img' and self.in_object == 0: - self.image_count += 1 - - def handle_endtag(self, tag): - if tag == 'object': - # Never let in_object be negative - self.in_object = max(0, self.in_object - 1) - - -def main(args=None): - parser = argparse.ArgumentParser() - parser.add_argument( - 'build_dir', metavar='build-dir', nargs='?', default='.', - help="The directory to scan for HTML files") - config = parser.parse_args(args) - - parser = MetricsParser() - for path in Path(config.build_dir).rglob('*.html'): - with path.open('r', encoding='utf-8', errors='replace') as f: - parser.read(f) - - print('Summarising metrics for build files (.html)...') - print(f'\tlinks: {parser.link_count} (' - f'{parser.fragment_count} #frag…, ' - f'{parser.int_link_count} /int…, ' - f'{parser.ext_link_count} https://ext…' - ')') - print(f'\timages: {parser.image_count}') - - -if __name__ == '__main__': - sys.exit(main()) diff --git a/docs/.sphinx/metrics/source_metrics.sh b/docs/.sphinx/metrics/source_metrics.sh deleted file mode 100755 index 07147d636..000000000 --- a/docs/.sphinx/metrics/source_metrics.sh +++ /dev/null @@ -1,66 +0,0 @@ -#!/bin/bash -# shellcheck disable=all - -VENV=".sphinx/venv/bin/activate" - -files=0 -words=0 -readabilityWords=0 -readabilitySentences=0 -readabilitySyllables=0 -readabilityAverage=0 -readable=true - -# measure number of files (.rst and .md), excluding those in .sphinx dir -files=$(find . -type d -path './.sphinx' -prune -o -type f \( -name '*.md' -o -name '*.rst' \) -print | wc -l) - -# calculate metrics only if source files are present -if [ "$files" -eq 0 ]; then - echo "There are no source files to calculate metrics" -else - # measure raw total number of words, excluding those in .sphinx dir - words=$(find . -type d -path './.sphinx' -prune -o \( -name '*.md' -o -name '*.rst' \) -exec cat {} + | wc -w) - - # calculate readability for markdown source files - echo "Activating virtual environment to run vale..." - source "${VENV}" - - for file in *.md *.rst; do - if [ -f "$file" ]; then - readabilityWords=$(vale ls-metrics "$file" | grep '"words"' | sed 's/[^0-9]*//g') - readabilitySentences=$(vale ls-metrics "$file" | grep '"sentences"' | sed 's/[^0-9]*//g') - readabilitySyllables=$(vale ls-metrics "$file" | grep '"syllables"' | sed 's/[^0-9]*//g') - fi - done - - echo "Deactivating virtual environment..." - deactivate - - # calculate mean number of words - if [ "$files" -ge 1 ]; then - meanval=$((readabilityWords / files)) - else - meanval=$readabilityWords - fi - - readabilityAverage=$(echo "scale=2; 0.39 * ($readabilityWords / $readabilitySentences) + (11.8 * ($readabilitySyllables / $readabilityWords)) - 15.59" | bc) - - # cast average to int for comparison - readabilityAverageInt=$(echo "$readabilityAverage / 1" | bc) - - # value below 8 is considered readable - if [ "$readabilityAverageInt" -lt 8 ]; then - readable=true - else - readable=false - fi - - # summarise latest metrics - echo "Summarising metrics for source files (.md, .rst)..." - echo -e "\ttotal files: $files" - echo -e "\ttotal words (raw): $words" - echo -e "\ttotal words (prose): $readabilityWords" - echo -e "\taverage word count: $meanval" - echo -e "\treadability: $readabilityAverage" - echo -e "\treadable: $readable" -fi diff --git a/docs/.sphinx/pa11y.json b/docs/.sphinx/pa11y.json deleted file mode 100644 index 04dc1e1c5..000000000 --- a/docs/.sphinx/pa11y.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "chromeLaunchConfig": { - "args": [ - "--no-sandbox" - ] - }, - "reporter": "cli", - "standard": "WCAG2AA" -} diff --git a/docs/.sphinx/spellingcheck.yaml b/docs/.sphinx/spellingcheck.yaml deleted file mode 100644 index 417a541cf..000000000 --- a/docs/.sphinx/spellingcheck.yaml +++ /dev/null @@ -1,30 +0,0 @@ -matrix: - - name: rST files - aspell: - lang: en - d: en_US - dictionary: - wordlists: - - .sphinx/.wordlist.txt - - .custom_wordlist.txt - output: .sphinx/.wordlist.dic - sources: - - _build/**/*.html - pipeline: - - pyspelling.filters.html: - comments: false - attributes: - - title - - alt - ignores: - - code - - pre - - spellexception - - link - - title - - div.relatedlinks - - strong.command - - div.visually-hidden - - img - - a.p-navigation__link - - a.contributor From b427df316287ba8ca3fe4da349dd3ade662b4d53 Mon Sep 17 00:00:00 2001 From: David Wilding Date: Tue, 23 Dec 2025 10:55:55 +0800 Subject: [PATCH 09/16] update docs workflow to check spelling and links --- .github/workflows/docs.yaml | 47 +++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index 3a5a0c7bc..22a3aee98 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -1,42 +1,39 @@ -# name: Docs on: push: branches: - - main + - master pull_request: - workflow_call: workflow_dispatch: -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true +permissions: {} jobs: - docchecks: - name: Checks - runs-on: ubuntu-22.04 - outputs: - linkcheck-result: ${{ steps.linkcheck-step.outcome }} + docs-spelling: + name: Spelling + runs-on: ubuntu-latest steps: - - name: Checkout - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: - fetch-depth: 0 - - name: Python + persist-credentials: false + - name: Set up Python uses: actions/setup-python@v6 with: python-version: "3.12" - - name: Links - id: linkcheck-step - if: success() || failure() - uses: canonical/documentation-workflows/linkcheck@main + - name: Check spelling + run: make -C docs spelling + + docs-linkcheck: + name: Links + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 with: - working-directory: docs - - name: Markdown lint - id: markdown-step - if: success() || failure() - uses: DavidAnson/markdownlint-cli2-action@v16 + persist-credentials: false + - name: Set up Python + uses: actions/setup-python@v6 with: - config: "docs/.sphinx/.markdownlint.json" + python-version: "3.12" + - name: Check links + run: make -C docs linkcheck From b5ff77d0b549d785fd2dbc14987547111810957a Mon Sep 17 00:00:00 2001 From: David Wilding Date: Wed, 24 Dec 2025 14:30:16 +0800 Subject: [PATCH 10/16] capitalize Unix --- docs/explanation/api-and-clients.md | 2 +- docs/explanation/general-model.md | 2 +- docs/index.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/explanation/api-and-clients.md b/docs/explanation/api-and-clients.md index c15bdf3e3..fd206d26f 100644 --- a/docs/explanation/api-and-clients.md +++ b/docs/explanation/api-and-clients.md @@ -1,6 +1,6 @@ # API and clients -The Pebble daemon exposes an API (HTTP over a unix socket) to allow remote clients to interact with the daemon. It can start and stop services, add configuration layers to the plan, and so on. +The Pebble daemon exposes an API (HTTP over a Unix socket) to allow remote clients to interact with the daemon. It can start and stop services, add configuration layers to the plan, and so on. If `pebble run` is started with the `--http
` option, Pebble also exposes open-access HTTP endpoints using the given TCP address (see {ref}`api-access-levels` below). diff --git a/docs/explanation/general-model.md b/docs/explanation/general-model.md index 3ad51342a..fbc8217d7 100644 --- a/docs/explanation/general-model.md +++ b/docs/explanation/general-model.md @@ -1,5 +1,5 @@ # General model -Pebble is organized as a single binary that works as a daemon and also as a client to itself. When the daemon runs it loads its own configuration from the `$PEBBLE` directory, as defined in the environment, and also records in that same directory its state and unix sockets for communication. If that variable is not defined, Pebble will attempt to look for its configuration from a default system-level setup at `/var/lib/pebble/default`. Using that directory is encouraged for whole-system setup such as when using Pebble to control services in a container. +Pebble is organized as a single binary that works as a daemon and also as a client to itself. When the daemon runs it loads its own configuration from the `$PEBBLE` directory, as defined in the environment, and also records in that same directory its state and Unix sockets for communication. If that variable is not defined, Pebble will attempt to look for its configuration from a default system-level setup at `/var/lib/pebble/default`. Using that directory is encouraged for whole-system setup such as when using Pebble to control services in a container. The `$PEBBLE` directory must contain a `layers/` subdirectory that holds a stack of configuration files with names similar to `001-base-layer.yaml`, where the digits define the order of the layer and the following label uniquely identifies it. Each layer in the stack sits above the former one, and has the chance to improve or redefine the service configuration as desired. diff --git a/docs/index.md b/docs/index.md index 99c828ae2..62fc12e50 100644 --- a/docs/index.md +++ b/docs/index.md @@ -14,7 +14,7 @@ explanation/index It helps you orchestrate a set of local processes as an organized set. It resembles well-known tools such as _supervisord_, _runit_, or _s6_, in that it can easily manage non-system processes independently from the system services. However, it was designed with unique features such as layered configuration and an HTTP API that help with more specific use cases. -If you need a way to manage one or more services in a container, or as a non-root user on a machine, Pebble might be for you. It handles service logs, service dependencies, and allows you to set up ongoing health checks. Plus, it has an "HTTP over unix socket" API for all operations, with simple UID-based access control. +If you need a way to manage one or more services in a container, or as a non-root user on a machine, Pebble might be for you. It handles service logs, service dependencies, and allows you to set up ongoing health checks. Plus, it has an "HTTP over Unix socket" API for all operations, with simple UID-based access control. Pebble is useful for developers who are building {external+operator:ref}`Juju charms on Kubernetes `, creating {external+rockcraft:ref}`Rock ` or Docker images, or orchestrating services in the virtual machine. From 9cac3553addb6bc4a06f35c9c7851814d54c5b5f Mon Sep 17 00:00:00 2001 From: David Wilding Date: Wed, 24 Dec 2025 14:38:59 +0800 Subject: [PATCH 11/16] change wording in comment (and add full stops) --- docs/reference/index.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/reference/index.md b/docs/reference/index.md index f4db96915..271d3a810 100644 --- a/docs/reference/index.md +++ b/docs/reference/index.md @@ -2,9 +2,9 @@ These guides provide technical information about Pebble. -% COMMENT: This toctree is for the navigation sidebar only -% Use an alphabetical listing of pages in the toctree -% For each page, make sure there's also a link in a section below +% COMMENT: This tree is for the navigation sidebar only. +% Use an alphabetical listing of pages in the tree. +% For each page, make sure there's also a link in a section below. ```{toctree} :hidden: @@ -24,7 +24,7 @@ Service auto-restart ``` -% COMMENT: The first few pages are presented in a more logical reading order +% COMMENT: The first few pages are presented in a more logical reading order. ## Layers From f44b7982ad0cb57367b57f6442f6ed29f373724d Mon Sep 17 00:00:00 2001 From: David Wilding Date: Wed, 24 Dec 2025 15:02:00 +0800 Subject: [PATCH 12/16] add code font and spelling exceptions --- docs/.custom_wordlist.txt | 14 ++++++++++++++ docs/explanation/api-and-clients.md | 4 ++-- docs/how-to/manage-identities.md | 6 +++--- docs/reference/api.md | 2 +- docs/reference/cli-commands.md | 6 +++--- docs/reference/environment-variables.md | 4 ++-- docs/reference/identities.md | 6 +++--- docs/reference/log-forwarding.md | 2 +- 8 files changed, 29 insertions(+), 15 deletions(-) diff --git a/docs/.custom_wordlist.txt b/docs/.custom_wordlist.txt index 734fdade6..4c41c430a 100644 --- a/docs/.custom_wordlist.txt +++ b/docs/.custom_wordlist.txt @@ -1 +1,15 @@ # Leave a blank line at the end of this file to support concatenation +backoff +boolean +Drepper +idempotently +liveness +ns +runit +replan +subcommands +supervisord +systemd +UIDs +Ulrich +Utils diff --git a/docs/explanation/api-and-clients.md b/docs/explanation/api-and-clients.md index fd206d26f..5047fe072 100644 --- a/docs/explanation/api-and-clients.md +++ b/docs/explanation/api-and-clients.md @@ -52,7 +52,7 @@ Currently the supported authentication types are: - `local`: a local user ID determined using peer credentials. - `basic`: HTTP basic authentication. -An example admin identity named "bob" with `local` type is shown below: +An example admin identity named `bob` with `local` type is shown below: ```yaml identities: @@ -62,7 +62,7 @@ identities: user-id: 42 ``` -An example identity named "alice" with `basic` type and `metrics` access level is shown below: +An example identity named `alice` with `basic` type and `metrics` access level is shown below: ```yaml identities: diff --git a/docs/how-to/manage-identities.md b/docs/how-to/manage-identities.md index ef5d0bdb0..f6ba0414b 100644 --- a/docs/how-to/manage-identities.md +++ b/docs/how-to/manage-identities.md @@ -10,7 +10,7 @@ By default any UID (user ID) connected to the API socket is a `read` user; UID 0 ## Add new identities -To extend access to Pebble's API to additional users, add named identities using the [`add-identities`](#reference_pebble_add-identities_command) command with a YAML file configuring the details. For example, to add a new admin "bob" with UID 42 and a new read user "alice" with UID 2000, prepare this file: +To extend access to Pebble's API to additional users, add named identities using the [`add-identities`](#reference_pebble_add-identities_command) command with a YAML file configuring the details. For example, to add a new admin `bob` with UID 42 and a new read user `alice` with UID 2000, prepare this file: ```yaml # idents-add.yaml @@ -37,7 +37,7 @@ Added 2 new identities. ## Remove identities -To remove existing identities, use [`remove-identities`](#reference_pebble_remove-identities_command) with a YAML file that has a `null` value for each identity you want to remove. For example, to remove "alice", prepare this file: +To remove existing identities, use [`remove-identities`](#reference_pebble_remove-identities_command) with a YAML file that has a `null` value for each identity you want to remove. For example, to remove `alice`, prepare this file: ```yaml # idents-remove.yaml @@ -75,7 +75,7 @@ pebble update-identities --from idents-update.yaml Updated 1 identity. ``` -You can use the `--replace` flag to idempotently add or update (or even remove) identities, whether or not they exist. The replace option is useful in automated scripts. For example, to update "bob", add "alice", and remove "mallory" (if it exists), prepare this file: +You can use the `--replace` flag to idempotently add or update (or even remove) identities, whether or not they exist. The replace option is useful in automated scripts. For example, to update `bob`, add `alice`, and remove `mallory` (if it exists), prepare this file: ```yaml # idents-replace.yaml diff --git a/docs/reference/api.md b/docs/reference/api.md index 51a0b61f3..162f82515 100644 --- a/docs/reference/api.md +++ b/docs/reference/api.md @@ -77,7 +77,7 @@ Some `GET` requests take optional query parameters for configuring or filterin All data sent to the API in `POST` bodies and all response data from the API is in JSON format. Requests should have a `Content-Type: application/json` header. -There are two main types of requests: synchronous ("sync"), and asynchronous ("async") for operations that can take some time to execute. Synchronous responses have the following structure: +There are two main types of requests: synchronous (`sync`), and asynchronous (`async`) for operations that can take some time to execute. Synchronous responses have the following structure: ```json { diff --git a/docs/reference/cli-commands.md b/docs/reference/cli-commands.md index adfee1555..80cbaa07b 100644 --- a/docs/reference/cli-commands.md +++ b/docs/reference/cli-commands.md @@ -218,7 +218,7 @@ pebble exec pg_dump mydb ... ``` -The exec feature uses WebSockets under the hood, and allows you to stream stdin to the process, as well as stream stdout and stderr back. When running `pebble exec`, you can specify the working directory to run in (`-w`), environment variables to set (`--env`), and the user and group to run as (`--uid`/`--user` and `--gid`/`--group`). +The exec feature uses WebSockets under the hood, and allows you to stream `stdin` to the process, as well as stream `stdout` and `stderr` back. When running `pebble exec`, you can specify the working directory to run in (`-w`), environment variables to set (`--env`), and the user and group to run as (`--uid`/`--user` and `--gid`/`--group`). You can also apply a timeout with `--timeout`, for example: @@ -361,7 +361,7 @@ The identity command shows details for a single identity in YAML format. (reference_pebble_logs_command)= ## logs -The Pebble daemon's service manager stores the most recent stdout and stderr from each service, using a 100KB ring buffer per service. Each log line is prefixed with an RFC-3339 timestamp and the `[service-name]` in square brackets. +The Pebble daemon's service manager stores the most recent `stdout` and `stderr` from each service, using a 100KB ring buffer per service. Each log line is prefixed with an RFC-3339 timestamp and the `[service-name]` in square brackets. Logs are viewable via the logs API or using `pebble logs`: @@ -419,7 +419,7 @@ pebble logs --format=json {"time":"2022-11-14T01:39:13.889Z","service":"srv1","message":"Log 1 from srv1"} ``` -If you want to also write service logs to Pebble's own stdout, run the daemon with `--verbose`: +If you want to also write service logs to Pebble's own `stdout`, run the daemon with `--verbose`: ```{terminal} pebble run --verbose diff --git a/docs/reference/environment-variables.md b/docs/reference/environment-variables.md index c6127a4b7..286a3eb7a 100644 --- a/docs/reference/environment-variables.md +++ b/docs/reference/environment-variables.md @@ -14,7 +14,7 @@ This will only copy the contents if the target directory, `$PEBBLE`, is empty. ## PEBBLE_DEBUG -If set to "1", debug logs will be printed to stderr. +If set to "1", debug logs will be printed to `stderr`. ## PEBBLE_PERSIST @@ -26,7 +26,7 @@ Pebble socket path. Defaults to `$PEBBLE/.pebble.socket` if not specified, or `/ ## PEBBLE_VERBOSE -If set to "1", the Pebble daemon writes service logs to stdout. +If set to "1", the Pebble daemon writes service logs to `stdout`. For `pebble run`, either `PEBBLE_VERBOSE=1` or the `--verbose` flag turns on verbose logging, with the command line flag overriding the environment variable. diff --git a/docs/reference/identities.md b/docs/reference/identities.md index 4b79bbeff..146488b08 100644 --- a/docs/reference/identities.md +++ b/docs/reference/identities.md @@ -29,7 +29,7 @@ identities: password: ``` -For example, a local identity named "bob" with UID 42 that is granted `admin` access would be defined as follows: +For example, a local identity named `bob` with UID 42 that is granted `admin` access would be defined as follows: ```yaml identities: @@ -39,7 +39,7 @@ identities: user-id: 42 ``` -For another example, a basic identity named "alice" that is granted `metrics` access would be defined as follows: +For another example, a basic identity named `alice` that is granted `metrics` access would be defined as follows: ```yaml identities: @@ -50,4 +50,4 @@ identities: password: ``` -The password is hashed using sha512-crypt, as generated by "openssl passwd -6". +The password is hashed using sha512-crypt, as generated by `openssl passwd -6`. diff --git a/docs/reference/log-forwarding.md b/docs/reference/log-forwarding.md index 8229f0404..11534cc49 100644 --- a/docs/reference/log-forwarding.md +++ b/docs/reference/log-forwarding.md @@ -22,7 +22,7 @@ Required configuration: - `override`: How this log target definition is combined with other pre-existing definitions with the same name in the plan. Supported values are `merge` and `replace`. - `type`: The type of log target. Supported types are `loki`, `opentelemetry` and `syslog`. -- `location`: The URL of the remote log target. For Loki, this needs to be the fully-qualified URL of the push API, including the API endpoint; use the format `http://:3100/loki/api/v1/push`. For OpenTelemetry, include the TCP port (normally 4318) without the API endpoint, for example: `http://:4318`. For Syslog, this needs to be either `tcp://:` or `udp://:`. +- `location`: The URL of the remote log target. For Loki, this needs to be the fully-qualified URL of the push API, including the API endpoint; use the format `http://:3100/loki/api/v1/push`. For OpenTelemetry, include the TCP port (normally 4318) without the API endpoint, for example: `http://:4318`. For `syslog`, this needs to be either `tcp://:` or `udp://:`. Optional configuration: From e8948ecbce34ccecb8f72b2878341d7969813d24 Mon Sep 17 00:00:00 2001 From: David Wilding Date: Wed, 24 Dec 2025 15:02:22 +0800 Subject: [PATCH 13/16] remove comment that's duplicated in text --- docs/reference/identities.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/reference/identities.md b/docs/reference/identities.md index 146488b08..75bd17859 100644 --- a/docs/reference/identities.md +++ b/docs/reference/identities.md @@ -46,7 +46,6 @@ identities: alice: access: metrics basic: - # The password is hashed using sha512-crypt, as generated by "openssl passwd -6". password: ``` From d0a6ddf673a469ddf8c8e38f0523fde6c3e9f717 Mon Sep 17 00:00:00 2001 From: David Wilding Date: Wed, 24 Dec 2025 15:03:09 +0800 Subject: [PATCH 14/16] fix genuine spelling mistake --- docs/explanation/security.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/explanation/security.md b/docs/explanation/security.md index 4a47d84d2..a0a3bcd31 100644 --- a/docs/explanation/security.md +++ b/docs/explanation/security.md @@ -49,4 +49,4 @@ Our intention is that projects that build on Pebble can [override how TLS connec ### FIPS 140 -This project also distributes [FIPS 140](https://en.wikipedia.org/wiki/FIPS_140)-compliant builds of Pebble: the source code is in the `fips` branch and there's the `fips` track for the official [`pebble` snap](https://snapcraft.io/pebble). Refer to [HACKING.md](https://github.com/canonical/pebble/blob/fips/HACKING.md#fips-140-changes) in the `fips` branch for the list of limiations in the FIPS builds. +This project also distributes [FIPS 140](https://en.wikipedia.org/wiki/FIPS_140)-compliant builds of Pebble: the source code is in the `fips` branch and there's the `fips` track for the official [`pebble` snap](https://snapcraft.io/pebble). Refer to [HACKING.md](https://github.com/canonical/pebble/blob/fips/HACKING.md#fips-140-changes) in the `fips` branch for the list of limitations in the FIPS builds. From 98caa1b48df642d3e5e46fa929fe09c680975efb Mon Sep 17 00:00:00 2001 From: David Wilding Date: Wed, 24 Dec 2025 15:05:15 +0800 Subject: [PATCH 15/16] reword to avoid "args" (and for clarity) --- docs/reference/cli-commands.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/reference/cli-commands.md b/docs/reference/cli-commands.md index 80cbaa07b..f645eeec8 100644 --- a/docs/reference/cli-commands.md +++ b/docs/reference/cli-commands.md @@ -970,7 +970,7 @@ More ways to run the daemon: pebble run --args myservice --verbose --foo "multi str arg" ``` -* Use args terminator to pass `--hold` to Pebble at the end of the line: +* Use the argument terminator `;` to pass `--hold` to Pebble: ```bash pebble run --args myservice --verbose \; --hold From 19d27128b671dd716602ed98921f5c55709cb328 Mon Sep 17 00:00:00 2001 From: David Wilding Date: Wed, 24 Dec 2025 15:30:24 +0800 Subject: [PATCH 16/16] exclude 'mkdir' because of the CLI command links --- docs/.custom_wordlist.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/.custom_wordlist.txt b/docs/.custom_wordlist.txt index 4c41c430a..4757c08db 100644 --- a/docs/.custom_wordlist.txt +++ b/docs/.custom_wordlist.txt @@ -4,6 +4,7 @@ boolean Drepper idempotently liveness +mkdir ns runit replan