]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
python/knot_resolver: new architecture
authorAleš Mrázek <ales.mrazek@nic.cz>
Mon, 29 Jun 2026 22:44:17 +0000 (00:44 +0200)
committerAleš Mrázek <ales.mrazek@nic.cz>
Tue, 30 Jun 2026 23:11:37 +0000 (01:11 +0200)
21 files changed:
python/knot_resolver/__init__.py [new file with mode: 0644]
python/knot_resolver/__main__.py [new file with mode: 0644]
python/knot_resolver/client/__init__.py [new file with mode: 0644]
python/knot_resolver/client/__main__.py [new file with mode: 0644]
python/knot_resolver/client/main.py [new file with mode: 0644]
python/knot_resolver/config/__init__.py [new file with mode: 0644]
python/knot_resolver/constants.py [new file with mode: 0644]
python/knot_resolver/constants.py.in [new file with mode: 0644]
python/knot_resolver/controller/__init__.py [new file with mode: 0644]
python/knot_resolver/errors.py [new file with mode: 0644]
python/knot_resolver/main.py [new file with mode: 0644]
python/knot_resolver/manager/__init__.py [new file with mode: 0644]
python/knot_resolver/manager/__main__.py [new file with mode: 0644]
python/knot_resolver/manager/errors.py [new file with mode: 0644]
python/knot_resolver/manager/main.py [new file with mode: 0644]
python/knot_resolver/meson.build [new file with mode: 0644]
python/knot_resolver/utils/__init__.py [new file with mode: 0644]
scripts/poe-tasks/check-code
scripts/poe-tasks/fix-format
scripts/poe-tasks/test-unit
tests/python/knot_resolver/test_knot_resolver.py [new file with mode: 0644]

diff --git a/python/knot_resolver/__init__.py b/python/knot_resolver/__init__.py
new file mode 100644 (file)
index 0000000..fb1533f
--- /dev/null
@@ -0,0 +1,3 @@
+from .constants import VERSION
+
+__version__ = VERSION
diff --git a/python/knot_resolver/__main__.py b/python/knot_resolver/__main__.py
new file mode 100644 (file)
index 0000000..40e2b01
--- /dev/null
@@ -0,0 +1,4 @@
+from .main import main
+
+if __name__ == "__main__":
+    main()
diff --git a/python/knot_resolver/client/__init__.py b/python/knot_resolver/client/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/python/knot_resolver/client/__main__.py b/python/knot_resolver/client/__main__.py
new file mode 100644 (file)
index 0000000..40e2b01
--- /dev/null
@@ -0,0 +1,4 @@
+from .main import main
+
+if __name__ == "__main__":
+    main()
diff --git a/python/knot_resolver/client/main.py b/python/knot_resolver/client/main.py
new file mode 100644 (file)
index 0000000..047ac14
--- /dev/null
@@ -0,0 +1,2 @@
+def main() -> None:
+    pass
diff --git a/python/knot_resolver/config/__init__.py b/python/knot_resolver/config/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/python/knot_resolver/constants.py b/python/knot_resolver/constants.py
new file mode 100644 (file)
index 0000000..63f11d5
--- /dev/null
@@ -0,0 +1,51 @@
+import importlib.util
+import platform
+import re
+from pathlib import Path
+
+VERSION = "6.4.0"
+USER = "knot-resolver"
+GROUP = "knot-resolver"
+
+# dirs paths
+RUN_DIR = Path("/run/knot-resolver")
+ETC_DIR = Path("/etc/knot-resolver")
+BIN_DIR = Path("/usr/bin")
+SBIN_DIR = Path("/usr/sbin")
+CACHE_DIR = Path("/var/cache/knot-resolver")
+
+# files paths
+CONFIG_FILE = ETC_DIR / "config.yaml"
+API_SOCK_FILE = RUN_DIR / "kres-api.sock"
+
+# executables paths
+KRESD_EXECUTABLE = SBIN_DIR / "kresd"
+KRES_CACHE_GC_EXECUTABLE = SBIN_DIR / "kres-cache-gc"
+KRES_MANAGER_EXECUTABLE = BIN_DIR / "kres-manager"
+
+LINUX_SYS = platform.system() == "Linux"
+FREEBSD_SYS = platform.system() == "FreeBSD"
+
+WATCHDOG_LIB = bool(importlib.util.find_spec("watchdog"))
+PROMETHEUS_LIB = bool(importlib.util.find_spec("prometheus_client"))
+
+
+def _freebsd_workers_support() -> bool:
+    if FREEBSD_SYS:
+        release = platform.release()
+        match = re.match(r"(\d+)", release)
+        if match:
+            freebsd_min_version = 12
+            return int(match.group(1)) >= freebsd_min_version
+    return False
+
+
+# It is possible to configure multiple kresd workers on Linux systems due to the SO_REUSEPORT socket option.
+# FreeBSD version >=12 supports it specifically due to the additional SO_REUSEPORT_LB socket option.
+WORKERS_SUPPORT = LINUX_SYS or _freebsd_workers_support()
+
+# default maximum number of workers
+WORKERS_MAX = 256
+
+# Systemd-like NOTIFY message is supported only on Linux systems
+NOTIFY_SUPPORT = LINUX_SYS
diff --git a/python/knot_resolver/constants.py.in b/python/knot_resolver/constants.py.in
new file mode 100644 (file)
index 0000000..901a5a6
--- /dev/null
@@ -0,0 +1,51 @@
+import importlib.util
+import platform
+import re
+from pathlib import Path
+
+VERSION = "@version@"
+USER = "@user@"
+GROUP = "@group@"
+
+# dirs paths
+RUN_DIR = Path("@run_dir@")
+ETC_DIR = Path("@etc_dir@")
+BIN_DIR = Path("@bin_dir@")
+SBIN_DIR = Path("@sbin_dir@")
+CACHE_DIR = Path("@cache_dir@")
+
+# files paths
+CONFIG_FILE = ETC_DIR / "config.yaml"
+API_SOCK_FILE = RUN_DIR / "kres-api.sock"
+
+# executables paths
+KRESD_EXECUTABLE = SBIN_DIR / "kresd"
+KRES_CACHE_GC_EXECUTABLE = SBIN_DIR / "kres-cache-gc"
+KRES_MANAGER_EXECUTABLE = BIN_DIR / "kres-manager"
+
+LINUX_SYS = platform.system() == "Linux"
+FREEBSD_SYS = platform.system() == "FreeBSD"
+
+WATCHDOG_LIB = bool(importlib.util.find_spec("watchdog"))
+PROMETHEUS_LIB = bool(importlib.util.find_spec("prometheus_client"))
+
+
+def _freebsd_workers_support() -> bool:
+    if FREEBSD_SYS:
+        release = platform.release()
+        match = re.match(r"(\d+)", release)
+        if match:
+            freebsd_min_version = 12
+            return int(match.group(1)) >= freebsd_min_version
+    return False
+
+
+# It is possible to configure multiple kresd workers on Linux systems due to the SO_REUSEPORT socket option.
+# FreeBSD version >=12 supports it specifically due to the additional SO_REUSEPORT_LB socket option.
+WORKERS_SUPPORT = LINUX_SYS or _freebsd_workers_support()
+
+# default maximum number of workers
+WORKERS_MAX = 256
+
+# Systemd-like NOTIFY message is supported only on Linux systems
+NOTIFY_SUPPORT = LINUX_SYS
diff --git a/python/knot_resolver/controller/__init__.py b/python/knot_resolver/controller/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/python/knot_resolver/errors.py b/python/knot_resolver/errors.py
new file mode 100644 (file)
index 0000000..b88d972
--- /dev/null
@@ -0,0 +1,2 @@
+class BaseKresError(Exception):
+    """Base class for all errors used in Knot Resolver modules."""
diff --git a/python/knot_resolver/main.py b/python/knot_resolver/main.py
new file mode 100644 (file)
index 0000000..e636c18
--- /dev/null
@@ -0,0 +1,5 @@
+from __future__ import annotations
+
+
+def main() -> None:
+    pass
diff --git a/python/knot_resolver/manager/__init__.py b/python/knot_resolver/manager/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/python/knot_resolver/manager/__main__.py b/python/knot_resolver/manager/__main__.py
new file mode 100644 (file)
index 0000000..40e2b01
--- /dev/null
@@ -0,0 +1,4 @@
+from .main import main
+
+if __name__ == "__main__":
+    main()
diff --git a/python/knot_resolver/manager/errors.py b/python/knot_resolver/manager/errors.py
new file mode 100644 (file)
index 0000000..5edf0ef
--- /dev/null
@@ -0,0 +1,5 @@
+from knot_resolver.errors import BaseKresError
+
+
+class KresManagerError(BaseKresError):
+    """Class for all errors used in manager submodules."""
diff --git a/python/knot_resolver/manager/main.py b/python/knot_resolver/manager/main.py
new file mode 100644 (file)
index 0000000..047ac14
--- /dev/null
@@ -0,0 +1,2 @@
+def main() -> None:
+    pass
diff --git a/python/knot_resolver/meson.build b/python/knot_resolver/meson.build
new file mode 100644 (file)
index 0000000..edd013f
--- /dev/null
@@ -0,0 +1,18 @@
+# python
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+constants_config = configuration_data()
+constants_config.set('version', meson.project_version())
+constants_config.set('user', user)
+constants_config.set('group', group)
+constants_config.set('run_dir', run_dir)
+constants_config.set('etc_dir', etc_dir)
+constants_config.set('bin_dir', bin_dir)
+constants_config.set('sbin_dir', sbin_dir)
+constants_config.set('cache_dir', systemd_cache_dir)
+
+configure_file(
+  input: 'constants.py.in',
+  output: 'constants.py',
+  configuration: constants_config,
+)
diff --git a/python/knot_resolver/utils/__init__.py b/python/knot_resolver/utils/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
index 7c89841f4a9dfc476e5254c250a042e2d30b3127..46a2ea26dd15ad43f0dd9755f44068c530a5838f 100755 (executable)
@@ -8,7 +8,7 @@ source $src_dir/utils/_env.sh
 set +e
 
 # dirs to check
-dirs="python/knot_resolver/ tests/manager"
+dirs="python/knot_resolver/ tests/python/knot_resolver"
 
 # check imports
 echo -e "${yellow}Checking Python imports using Ruff...${reset}"
index be2bf038ddfdd4cb361254186124acc5c9b0d879..2d942875bdccdfd40f959259900cb1e1e3eafb32 100755 (executable)
@@ -4,7 +4,7 @@
 src_dir="$(dirname "$(realpath "$0")")"
 source $src_dir/utils/_env.sh
 
-dirs="python/knot_resolver/ tests/manager"
+dirs="python/knot_resolver/ tests/python/knot_resolver"
 
 # sort python import
 echo -e "${yellow}Sorting Python imports using ruff...${reset}"
index 85fd6089a79a95ab65ac73024719dd0e08e5174c..9560374e09016458076d4973787d0974152a8b4e 100755 (executable)
@@ -5,4 +5,4 @@ src_dir="$(dirname "$(realpath "$0")")"
 source $src_dir/utils/_env.sh
 
 # run pytest
-env PYTHONPATH=. pytest --junitxml=unit.junit.xml --cov=python/knot_resolver --show-capture=all tests/manager
+env PYTHONPATH=. pytest --junitxml=unit.junit.xml --cov=python/knot_resolver --show-capture=all tests/python/knot_resolver
diff --git a/tests/python/knot_resolver/test_knot_resolver.py b/tests/python/knot_resolver/test_knot_resolver.py
new file mode 100644 (file)
index 0000000..a4a4fb6
--- /dev/null
@@ -0,0 +1,8 @@
+from knot_resolver import __version__
+
+
+def test_version() -> None:
+    with open("VERSION", "r") as version_file:
+        version = version_file.read().strip()
+
+    assert __version__ == version