diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ac73ec2b..7605f204 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -101,7 +101,7 @@ repos: name: pytest unit tests and static analysis using tox types: [python] # entry: sh -c "pytest -x -rf --new-first --show-capture=all >/dev/tty" - entry: sh -c "tox -e py311-cov-check-pytype-pyright-lint-mdreport >/dev/tty" + entry: sh -c "tox -e py311-cov-check-pytype-pyright-lint-docs-mdreport >/dev/tty" verbose: true language: python require_serial: true diff --git a/docs/Makefile b/docs/Makefile index d0c3cbf1..bed4efb2 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -17,4 +17,4 @@ help: # Catch-all target: route all unknown targets to Sphinx using the new # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). %: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + $(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/source/conf.py b/docs/source/conf.py index 97d79512..9ef263a1 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -55,4 +55,5 @@ # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output html_theme = "furo" -html_static_path = ["_static"] +# No static html source files for now. +# html_static_path = ["_static"] diff --git a/docs/source/index.rst b/docs/source/index.rst index b8def097..b331b134 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -18,6 +18,11 @@ XenServer Python libs for Dom0 .. image:: https://img.shields.io/badge/Sphinx-docs-blue.svg :target: https://python-libs.onrender.com/ +Welcome to the python-libs documentation! + +Each module is documented in its own section. +Select a module from the menu to view its API documentation. + .. toctree:: :maxdepth: 2 :caption: Project Documentation @@ -46,7 +51,20 @@ XenServer Python libs for Dom0 version xmlunwrap -Welcome to the python-libs documentation! +.. toctree:: + :maxdepth: 2 + :caption: XCP.Net Modules + + net/biosdevname + net/ip + net/mac -Each module is documented in its own section. Select a module from the menu to view its API documentation. +.. toctree:: + :maxdepth: 2 + :caption: XCP.Net.Ifrename Modules + net/ifrename/ifrename-util + net/ifrename/ifrename-static + net/ifrename/ifrename-logic + net/ifrename/ifrename-dynamic + net/ifrename/ifrename-macpci diff --git a/docs/source/net/biosdevname.rst b/docs/source/net/biosdevname.rst new file mode 100644 index 00000000..b9647e61 --- /dev/null +++ b/docs/source/net/biosdevname.rst @@ -0,0 +1,7 @@ +xcp.net.biosdevname +=================== + +.. automodule:: xcp.net.biosdevname + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/net/ifrename/ifrename-dynamic.rst b/docs/source/net/ifrename/ifrename-dynamic.rst new file mode 100644 index 00000000..cfcb648b --- /dev/null +++ b/docs/source/net/ifrename/ifrename-dynamic.rst @@ -0,0 +1,7 @@ +xcp.net.ifrename.dynamic +======================== + +.. automodule:: xcp.net.ifrename.dynamic + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/net/ifrename/ifrename-logic.rst b/docs/source/net/ifrename/ifrename-logic.rst new file mode 100644 index 00000000..0606fb6d --- /dev/null +++ b/docs/source/net/ifrename/ifrename-logic.rst @@ -0,0 +1,7 @@ +xcp.net.ifrename.logic +====================== + +.. automodule:: xcp.net.ifrename.logic + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/net/ifrename/ifrename-macpci.rst b/docs/source/net/ifrename/ifrename-macpci.rst new file mode 100644 index 00000000..a6f3f987 --- /dev/null +++ b/docs/source/net/ifrename/ifrename-macpci.rst @@ -0,0 +1,7 @@ +xcp.net.ifrename.macpci +======================= + +.. automodule:: xcp.net.ifrename.macpci + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/net/ifrename/ifrename-static.rst b/docs/source/net/ifrename/ifrename-static.rst new file mode 100644 index 00000000..afc9c7ef --- /dev/null +++ b/docs/source/net/ifrename/ifrename-static.rst @@ -0,0 +1,7 @@ +xcp.net.ifrename.static +======================= + +.. automodule:: xcp.net.ifrename.static + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/net/ifrename/ifrename-util.rst b/docs/source/net/ifrename/ifrename-util.rst new file mode 100644 index 00000000..3b288e6f --- /dev/null +++ b/docs/source/net/ifrename/ifrename-util.rst @@ -0,0 +1,7 @@ +xcp.net.ifrename.util +===================== + +.. automodule:: xcp.net.ifrename.util + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/net/ip.rst b/docs/source/net/ip.rst new file mode 100644 index 00000000..6981fc6b --- /dev/null +++ b/docs/source/net/ip.rst @@ -0,0 +1,7 @@ +xcp.net.ip +========== + +.. automodule:: xcp.net.ip + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/net/mac.rst b/docs/source/net/mac.rst new file mode 100644 index 00000000..414c8320 --- /dev/null +++ b/docs/source/net/mac.rst @@ -0,0 +1,7 @@ +xcp.net.mac +=========== + +.. automodule:: xcp.net.mac + :members: + :undoc-members: + :show-inheritance: diff --git a/tox.ini b/tox.ini index 82d52514..13b65e1d 100644 --- a/tox.ini +++ b/tox.ini @@ -12,7 +12,7 @@ min_version = 4.6 # .github/workflows/main.yml is set up to test with 3.11, 3.12 and 3.13 in parallel. # Therefore, use three environments: One with 3.11, one with 3.12 and one with 3.13: # -envlist = py311-covcp-check-pytype-mdreport, py312-cov, py313-cov-lint-pyright +envlist = py311-covcp-check-pytype-mdreport, py312-cov-docs, py313-cov-lint-pyright isolated_build = true skip_missing_interpreters = true requires = @@ -37,6 +37,7 @@ commands = description = Run in a {basepython} virtualenv: cov: {[cov]description} covcp: Copy the generated .converage and coverage.xml to the UPLOAD_DIR dir + docs: {[docs]description} fox: {[fox]description} lint: {[lint]description} mdreport: Make a test report (which is shown in the GitHub Actions Summary Page) @@ -56,12 +57,14 @@ deps = {cov,covcp,fox}: coverage[toml] {cov,covcp,fox}: diff-cover {lint,fox}: {[lint]deps} + docs: {[docs]deps} pyright: pyright allowlist_externals = {cov,covcp,fox,check,lint,test,mdreport}: echo {cov,covcp,fox,check,lint,test,mdreport}: sh {cov,covcp,fox}: cp check: cat + docs: make fox: firefox passenv = {pytype,lint,test}: GITHUB_STEP_SUMMARY @@ -99,6 +102,7 @@ setenv = lint: ENVLOGDIR={envlogdir} {[cov]setenv} commands = + docs: {[docs]commands} lint: {[lint]commands} pyright: {[pyright]commands} check: {[check]commands} @@ -126,6 +130,13 @@ commands = --html-report {envlogdir}/coverage-diff.html \ {envlogdir}/coverage.xml + +[docs] +description = Build the documentation to check for errors +deps = -r docs/requirements.txt +commands = make -C docs html SPHINXOPTS="--fail-on-warning" + + [lint] description = Run pylint and fail on warnings remaining on lines in the diff to master deps = pylint diff --git a/xcp/net/ifrename/logic.py b/xcp/net/ifrename/logic.py index 476dc2d7..77806209 100644 --- a/xcp/net/ifrename/logic.py +++ b/xcp/net/ifrename/logic.py @@ -39,6 +39,10 @@ [out] transactions list of string tuples as source and destination names for "ip link set name" + +Terms and abbreviations used in this file: + kname: The kernel name of the network interface (the original name assigned by the kernel). + tname: The temporary name of the interface, used while renaming interfaces to avoid name conflicts. """ from __future__ import unicode_literals @@ -122,24 +126,32 @@ def __rename_nic(nic, name, transactions, cur_state): transactions.append((nic.kname, name)) -def rename_logic( static_rules, - cur_state, - last_state, - old_state ): +def rename_logic(static_rules, cur_state, last_state, old_state): """ Core logic of renaming the current state based on the rules and past state. + This function assumes all inputs have been suitably sanitised. - @param static_rules + + Parameters + ---------- + static_rules : List[MACPCI] List of MACPCI objects representing rules - @param cur_state + cur_state : List[MACPCI] List of MACPCI objects representing the current state - @param last_state + last_state : List[MACPCI] List of MACPCI objects representing the last boot state - @param old_state + old_state : List[MACPCI] List of MACPCI objects representing the old state - @returns List of tuples... - @throws AssertionError (Should not be thrown, but better to know about logic - errors if they occur) + + Returns + ------- + list + List of tuples representing name transactions. + + Raises + ------ + AssertionError + If the current state contains invalid entries. """ transactions = [] @@ -365,26 +377,44 @@ def rename_logic( static_rules, util.niceformat(cur_state))) return transactions -def rename( static_rules, - cur_state, - last_state, - old_state ): +def rename(static_rules, cur_state, last_state, old_state): """ Rename current state based on the rules and past state. - This function sanitises the input and delegates the renaming logic to - __rename. - @param static_rules + + This function: + - Sanitises the input + - Delegates the renaming logic to rename_logic() + + Parameters + ---------- + static_rules : List[MACPCI] List of MACPCI objects representing rules - @param cur_state + cur_state : List[MACPCI] List of MACPCI objects representing the current state - @param last_state + last_state : List[MACPCI] List of MACPCI objects representing the last boot state - @param old_state + old_state : List[MACPCI] List of MACPCI objects representing the old state - @throws StaticRuleError, CurrentStateError, LastStateError, TypeError - - @returns list of tuples of name changes required + Returns + ------- + list + List of tuples of name changes required + + Raises + ------ + StaticRuleError + Raised if any of the following conditions are met: + - A static rule has a kernel name. + - A static rule has a tname not starting with 'eth'. + - Duplicate eth names are present in static rules. + - Duplicate MAC addresses are present in static rules. + CurrentStateError + If the current state contains invalid entries. + LastStateError + If the last state contains invalid entries. + TypeError + If any of the input lists contain objects that are not MACPCI instances. """ if len(static_rules): diff --git a/xcp/net/ifrename/static.py b/xcp/net/ifrename/static.py index 76ab3723..2b4b9124 100644 --- a/xcp/net/ifrename/static.py +++ b/xcp/net/ifrename/static.py @@ -25,17 +25,16 @@ Object for manipulating static rules. Rules are of the form: - : = "value" + : = "value" -target name must be in the form eth* -id methods are: - mac: value should be the mac address of a device (e.g. DE:AD:C0:DE:00:00) - pci: value should be the pci bus location of the device, optionally with an index (e.g. 0000:01:01.1[0]) - ppn: value should be the result of the biosdevname physical naming policy of a device (e.g. p1p1) - label: value should be the SMBios label of a device (for SMBios 2.6 or above) - -Any line starting with '#' is considered to be a comment + target name must be in the form eth* + id methods are: + - `mac`: value should be the MAC address of a device (e.g. DE:AD:C0:DE:00:00) + - `pci`: value should be the PCI bus location of the device, optionally with an index (e.g. 0000:01:01.1[0]) + - `ppn`: value should be the result of the biosdevname physical naming policy of a device (e.g. p1p1) + - `label`: value should be the SMBIOS label of a device (for SMBIOS 2.6 or above) + Any line starting with '#' is considered to be a comment """ from __future__ import unicode_literals @@ -71,10 +70,10 @@ # target name must be in the form eth* # id methods are: -# mac: value should be the mac address of a device (e.g. DE:AD:C0:DE:00:00) -# pci: value should be the pci bus location of the device (e.g. 0000:01:01.1[0]) +# mac: value should be the MAC address of a device (e.g. DE:AD:C0:DE:00:00) +# pci: value should be the PCI bus location of the device (e.g. 0000:01:01.1[0]) # ppn: value should be the result of the biosdevname physical naming policy of a device (e.g. p1p1) -# label: value should be the SMBios label of a device (for SMBios 2.6 or above) +# label: value should be the SMBIOS label of a device (for SMBIOS 2.6 or above) """