From 08fdacb5a7e9c1eb320c58a9b812d8cb7086cd4a Mon Sep 17 00:00:00 2001 From: "Adam C. Stephens" Date: Tue, 1 Apr 2025 18:25:56 +0000 Subject: [PATCH 1/5] pythonPackages.canonical-sphinx-extensions: init at 0.0.27 --- .../canonical-sphinx-extensions/default.nix | 44 +++++++++++++++++++ pkgs/top-level/python-packages.nix | 4 ++ 2 files changed, 48 insertions(+) create mode 100644 pkgs/development/python-modules/canonical-sphinx-extensions/default.nix diff --git a/pkgs/development/python-modules/canonical-sphinx-extensions/default.nix b/pkgs/development/python-modules/canonical-sphinx-extensions/default.nix new file mode 100644 index 000000000000..1ad27acb2833 --- /dev/null +++ b/pkgs/development/python-modules/canonical-sphinx-extensions/default.nix @@ -0,0 +1,44 @@ +{ + lib, + buildPythonPackage, + fetchPypi, + setuptools, + beautifulsoup4, + docutils, + gitpython, + requests, + sphinx, +}: + +buildPythonPackage rec { + pname = "canonical-sphinx-extensions"; + version = "0.0.27"; + pyproject = true; + + src = fetchPypi { + pname = "canonical_sphinx_extensions"; + inherit version; + hash = "sha256-ZorSmn+PAVS8xO7X3zk6u3W7pn3JB9w0PhFAXzv6l78="; + }; + + build-system = [ + setuptools + ]; + + dependencies = [ + beautifulsoup4 + docutils + gitpython + requests + sphinx + ]; + + doCheck = false; + + meta = { + description = "A collection of Sphinx extensions used by Canonical documentation"; + homepage = "https://pypi.org/project/canonical-sphinx-extensions"; + license = lib.licenses.asl20; + maintainers = with lib.maintainers; [ ]; + }; +} diff --git a/pkgs/top-level/python-packages.nix b/pkgs/top-level/python-packages.nix index 6d1b37581114..d7ac01cb0adf 100644 --- a/pkgs/top-level/python-packages.nix +++ b/pkgs/top-level/python-packages.nix @@ -2192,6 +2192,10 @@ self: super: with self; { canmatrix = callPackage ../development/python-modules/canmatrix { }; + canonical-sphinx-extensions = + callPackage ../development/python-modules/canonical-sphinx-extensions + { }; + canonicaljson = callPackage ../development/python-modules/canonicaljson { }; canopen = callPackage ../development/python-modules/canopen { }; From 9d55c960ba2c44941d18d0b6815987667b492fad Mon Sep 17 00:00:00 2001 From: "Adam C. Stephens" Date: Tue, 1 Apr 2025 18:25:56 +0000 Subject: [PATCH 2/5] pythonPackages.sphinx-reredirects: init at 0.1.6 --- .../sphinx-reredirects/default.nix | 41 +++++++++++++++++++ pkgs/top-level/python-packages.nix | 2 + 2 files changed, 43 insertions(+) create mode 100644 pkgs/development/python-modules/sphinx-reredirects/default.nix diff --git a/pkgs/development/python-modules/sphinx-reredirects/default.nix b/pkgs/development/python-modules/sphinx-reredirects/default.nix new file mode 100644 index 000000000000..8fc57ab6d1f0 --- /dev/null +++ b/pkgs/development/python-modules/sphinx-reredirects/default.nix @@ -0,0 +1,41 @@ +{ + lib, + buildPythonPackage, + fetchPypi, + setuptools, + sphinx, +}: + +buildPythonPackage rec { + pname = "sphinx-reredirects"; + version = "0.1.6"; + pyproject = true; + + src = fetchPypi { + pname = "sphinx_reredirects"; + inherit version; + hash = "sha256-xJHLpUX2e+lpdQhyeBjYYmYmNmJFrmRFb+KfN+m76mQ="; + }; + + build-system = [ + setuptools + ]; + + dependencies = [ + sphinx + ]; + + pythonImportsCheck = [ + "sphinx_reredirects" + ]; + + meta = { + description = "Handles redirects for moved pages in Sphinx documentation projects"; + homepage = "https://pypi.org/project/sphinx-reredirects"; + license = with lib.licenses; [ + bsd3 + mit + ]; + maintainers = with lib.maintainers; [ ]; + }; +} diff --git a/pkgs/top-level/python-packages.nix b/pkgs/top-level/python-packages.nix index d7ac01cb0adf..d638ae3aba7b 100644 --- a/pkgs/top-level/python-packages.nix +++ b/pkgs/top-level/python-packages.nix @@ -16171,6 +16171,8 @@ self: super: with self; { sphinx-pytest = callPackage ../development/python-modules/sphinx-pytest { }; + sphinx-reredirects = callPackage ../development/python-modules/sphinx-reredirects { }; + sphinx-rtd-dark-mode = callPackage ../development/python-modules/sphinx-rtd-dark-mode { }; sphinx-rtd-theme = callPackage ../development/python-modules/sphinx-rtd-theme { }; From e06dd5475e7bd5ea408a5797b9a21311e569a7e7 Mon Sep 17 00:00:00 2001 From: "Adam C. Stephens" Date: Tue, 1 Apr 2025 18:25:56 +0000 Subject: [PATCH 3/5] pythonPackages.pyspelling: init at 2.10 --- .../python-modules/pyspelling/default.nix | 49 +++++++++++++++++++ pkgs/top-level/python-packages.nix | 2 + 2 files changed, 51 insertions(+) create mode 100644 pkgs/development/python-modules/pyspelling/default.nix diff --git a/pkgs/development/python-modules/pyspelling/default.nix b/pkgs/development/python-modules/pyspelling/default.nix new file mode 100644 index 000000000000..78b5871c07b1 --- /dev/null +++ b/pkgs/development/python-modules/pyspelling/default.nix @@ -0,0 +1,49 @@ +{ + lib, + buildPythonPackage, + fetchPypi, + hatchling, + beautifulsoup4, + html5lib, + lxml, + markdown, + pyyaml, + soupsieve, + wcmatch, +}: + +buildPythonPackage rec { + pname = "pyspelling"; + version = "2.10"; + pyproject = true; + + src = fetchPypi { + inherit pname version; + hash = "sha256-rNZxM8G3zs1BDj1EieYfLksfC2rPGubEjCQPuyFynDc="; + }; + + build-system = [ + hatchling + ]; + + dependencies = [ + beautifulsoup4 + html5lib + lxml + markdown + pyyaml + soupsieve + wcmatch + ]; + + pythonImportsCheck = [ + "pyspelling" + ]; + + meta = { + description = "Spell checker"; + homepage = "https://pypi.org/project/pyspelling"; + license = lib.licenses.mit; + maintainers = with lib.maintainers; [ ]; + }; +} diff --git a/pkgs/top-level/python-packages.nix b/pkgs/top-level/python-packages.nix index d638ae3aba7b..18b328e3f7c8 100644 --- a/pkgs/top-level/python-packages.nix +++ b/pkgs/top-level/python-packages.nix @@ -13326,6 +13326,8 @@ self: super: with self; { pyspellchecker = callPackage ../development/python-modules/pyspellchecker { }; + pyspelling = callPackage ../development/python-modules/pyspelling { }; + pyspf = callPackage ../development/python-modules/pyspf { }; pyspice = callPackage ../development/python-modules/pyspice { }; From 923ae1752801ed0be8adb897237c66c1afbf2845 Mon Sep 17 00:00:00 2001 From: "Adam C. Stephens" Date: Tue, 1 Apr 2025 18:25:56 +0000 Subject: [PATCH 4/5] pythonPackages.sphinx-remove-toctrees: init at 1.0.0.post1 --- .../sphinx-remove-toctrees/default.nix | 60 +++++++++++++++++++ pkgs/top-level/python-packages.nix | 2 + 2 files changed, 62 insertions(+) create mode 100644 pkgs/development/python-modules/sphinx-remove-toctrees/default.nix diff --git a/pkgs/development/python-modules/sphinx-remove-toctrees/default.nix b/pkgs/development/python-modules/sphinx-remove-toctrees/default.nix new file mode 100644 index 000000000000..7f381ff997bd --- /dev/null +++ b/pkgs/development/python-modules/sphinx-remove-toctrees/default.nix @@ -0,0 +1,60 @@ +{ + lib, + buildPythonPackage, + fetchPypi, + hatchling, + sphinx, + pre-commit, + ipython, + myst-parser, + sphinx-book-theme, + pytest, +}: + +buildPythonPackage rec { + pname = "sphinx-remove-toctrees"; + version = "1.0.0.post1"; + pyproject = true; + + src = fetchPypi { + pname = "sphinx_remove_toctrees"; + inherit version; + hash = "sha256-SAjR7fFRwG7/bSw5Iux+vJ/Tqhdi3hsuFnSjf1rJzi0="; + }; + + build-system = [ + hatchling + ]; + + dependencies = [ + sphinx + ]; + + optional-dependencies = { + code_style = [ + pre-commit + ]; + docs = [ + ipython + myst-parser + sphinx-book-theme + ]; + tests = [ + ipython + myst-parser + pytest + sphinx-book-theme + ]; + }; + + pythonImportsCheck = [ + "sphinx_remove_toctrees" + ]; + + meta = { + description = "Reduce your documentation build size by selectively removing toctrees from pages"; + homepage = "https://pypi.org/project/sphinx-remove-toctrees/"; + license = lib.licenses.mit; + maintainers = with lib.maintainers; [ ]; + }; +} diff --git a/pkgs/top-level/python-packages.nix b/pkgs/top-level/python-packages.nix index 18b328e3f7c8..49d580780596 100644 --- a/pkgs/top-level/python-packages.nix +++ b/pkgs/top-level/python-packages.nix @@ -16175,6 +16175,8 @@ self: super: with self; { sphinx-reredirects = callPackage ../development/python-modules/sphinx-reredirects { }; + sphinx-remove-toctrees = callPackage ../development/python-modules/sphinx-remove-toctrees { }; + sphinx-rtd-dark-mode = callPackage ../development/python-modules/sphinx-rtd-dark-mode { }; sphinx-rtd-theme = callPackage ../development/python-modules/sphinx-rtd-theme { }; From 21197daa39ee07363242a7211145db641b40d879 Mon Sep 17 00:00:00 2001 From: "Adam C. Stephens" Date: Tue, 1 Apr 2025 18:25:56 +0000 Subject: [PATCH 5/5] incus: build and expose documentation --- nixos/modules/virtualisation/incus.nix | 1 + nixos/tests/incus/ui.nix | 4 +++ pkgs/by-name/in/incus/docs.patch | 26 +++++++++++++++ pkgs/by-name/in/incus/generic.nix | 45 ++++++++++++++++++++++---- 4 files changed, 70 insertions(+), 6 deletions(-) create mode 100644 pkgs/by-name/in/incus/docs.patch diff --git a/nixos/modules/virtualisation/incus.nix b/nixos/modules/virtualisation/incus.nix index 136cd20eee55..6637141d0330 100644 --- a/nixos/modules/virtualisation/incus.nix +++ b/nixos/modules/virtualisation/incus.nix @@ -129,6 +129,7 @@ let environment = lib.mkMerge [ { + INCUS_DOCUMENTATION = "${cfg.package.doc}/html"; INCUS_EDK2_PATH = ovmf; INCUS_LXC_HOOK = "${cfg.lxcPackage}/share/lxc/hooks"; INCUS_LXC_TEMPLATE_CONFIG = "${pkgs.lxcfs}/share/lxc/config"; diff --git a/nixos/tests/incus/ui.nix b/nixos/tests/incus/ui.nix index 27b90c218d78..300388a19f93 100644 --- a/nixos/tests/incus/ui.nix +++ b/nixos/tests/incus/ui.nix @@ -66,6 +66,7 @@ import ../make-test-python.nix ( testScript = '' machine.wait_for_unit("incus.service") + machine.wait_for_unit("incus-preseed.service") # Check that the INCUS_UI environment variable is populated in the systemd unit machine.succeed("systemctl cat incus.service | grep 'INCUS_UI'") @@ -73,6 +74,9 @@ import ../make-test-python.nix ( # Ensure the endpoint returns an HTML page with 'Incus UI' in the title machine.succeed("curl -kLs https://localhost:8443/ui | grep 'Incus UI'") + # Ensure the documentation is rendering correctly + machine.succeed("curl -kLs https://localhost:8443/documentation/ | grep 'Incus documentation'") + # Ensure the application is actually rendered by the Javascript machine.succeed("PYTHONUNBUFFERED=1 selenium-script") ''; diff --git a/pkgs/by-name/in/incus/docs.patch b/pkgs/by-name/in/incus/docs.patch new file mode 100644 index 000000000000..6857df48e230 --- /dev/null +++ b/pkgs/by-name/in/incus/docs.patch @@ -0,0 +1,26 @@ +diff --git i/doc/conf.py w/doc/conf.py +index 8d042818b..b4f0572bd 100644 +--- i/doc/conf.py ++++ w/doc/conf.py +@@ -8,10 +8,6 @@ import yaml + from git import Repo + import filecmp + +-# Download and link swagger-ui files +-if not os.path.isdir('.sphinx/deps/swagger-ui'): +- Repo.clone_from('https://github.com/swagger-api/swagger-ui', '.sphinx/deps/swagger-ui', depth=1) +- + os.makedirs('.sphinx/_static/swagger-ui/', exist_ok=True) + + if not os.path.islink('.sphinx/_static/swagger-ui/swagger-ui-bundle.js'): +@@ -151,10 +147,6 @@ if os.path.exists("./related_topics.yaml"): + with open("./related_topics.yaml", "r") as fd: + myst_substitutions.update(yaml.safe_load(fd.read())) + +-intersphinx_mapping = { +- 'cloud-init': ('https://cloudinit.readthedocs.io/en/latest/', None) +-} +- + if ("LOCAL_SPHINX_BUILD" in os.environ) and (os.environ["LOCAL_SPHINX_BUILD"] == "True"): + swagger_url_scheme = "/api/#{{path}}" + else: diff --git a/pkgs/by-name/in/incus/generic.nix b/pkgs/by-name/in/incus/generic.nix index be969c84e4a6..2620ea098c24 100644 --- a/pkgs/by-name/in/incus/generic.nix +++ b/pkgs/by-name/in/incus/generic.nix @@ -13,6 +13,7 @@ buildGoModule, fetchFromGitHub, acl, + buildPackages, cowsql, incus-ui-canonical, libcap, @@ -27,11 +28,30 @@ let pname = "incus${lib.optionalString lts "-lts"}"; + docsPython = buildPackages.python3.withPackages ( + py: with py; [ + furo + gitpython + linkify-it-py + canonical-sphinx-extensions + myst-parser + pyspelling + sphinx + sphinx-autobuild + sphinx-copybutton + sphinx-design + sphinx-notfound-page + sphinx-remove-toctrees + sphinx-reredirects + sphinx-tabs + sphinxcontrib-jquery + sphinxext-opengraph + ] + ); in -buildGoModule rec { +buildGoModule (finalAttrs: { inherit - patches pname vendorHash version @@ -40,15 +60,18 @@ buildGoModule rec { outputs = [ "out" "agent_loader" + "doc" ]; src = fetchFromGitHub { owner = "lxc"; repo = "incus"; - rev = "refs/tags/v${version}"; + tag = "v${version}"; inherit hash; }; + patches = [ ./docs.patch ] ++ patches; + excludedPackages = [ # statically compile these "cmd/incus-agent" @@ -61,6 +84,7 @@ buildGoModule rec { nativeBuildInputs = [ installShellFiles pkg-config + docsPython ]; buildInputs = [ @@ -82,6 +106,13 @@ buildGoModule rec { CGO_LDFLAGS_ALLOW = "(-Wl,-wrap,pthread_create)|(-Wl,-z,now)"; postBuild = '' + # build docs + mkdir -p .sphinx/deps + ln -s ${buildPackages.python3.pkgs.swagger-ui-bundle.src} .sphinx/deps/swagger-ui + substituteInPlace Makefile --replace-fail '. $(SPHINXENV) ; ' "" + make doc-incremental + + # build some static executables make incus-agent incus-migrate ''; @@ -111,18 +142,20 @@ buildGoModule rec { cp internal/server/instance/drivers/agent-loader/systemd/incus-agent.service $agent_loader/etc/systemd/system/ cp internal/server/instance/drivers/agent-loader/systemd/incus-agent.rules $agent_loader/lib/udev/rules.d/99-incus-agent.rules substituteInPlace $agent_loader/etc/systemd/system/incus-agent.service --replace-fail 'TARGET/systemd' "$agent_loader/bin" + + mkdir $doc + cp -R doc/html $doc/ ''; passthru = { client = callPackage ./client.nix { inherit lts - meta patches - src vendorHash version ; + inherit (finalAttrs) meta src; }; tests = if lts then nixosTests.incus-lts.all else nixosTests.incus.all; @@ -143,4 +176,4 @@ buildGoModule rec { platforms = lib.platforms.linux; mainProgram = "incus"; }; -} +})