diff options
author | Aleš Mrázek <ales.mrazek@nic.cz> | 2024-10-18 11:13:54 +0200 |
---|---|---|
committer | Vladimír Čunát <vladimir.cunat@nic.cz> | 2024-12-03 08:53:33 +0100 |
commit | 37e5ec79b718f3502d3e043657349e16feba9c62 (patch) | |
tree | 85b247625c9cda0ab34a724f732f4bbc68868d9d /python | |
parent | pyproject.toml: 'watchdog' added as optional dependency (diff) | |
download | knot-resolver-37e5ec79b718f3502d3e043657349e16feba9c62.tar.xz knot-resolver-37e5ec79b718f3502d3e043657349e16feba9c62.zip |
python/knot_resolver/manager: added files watchdog
Diffstat (limited to 'python')
-rw-r--r-- | python/knot_resolver/manager/files/__init__.py | 3 | ||||
-rw-r--r-- | python/knot_resolver/manager/files/watchdog.py | 88 | ||||
-rw-r--r-- | python/knot_resolver/manager/server.py | 4 |
3 files changed, 94 insertions, 1 deletions
diff --git a/python/knot_resolver/manager/files/__init__.py b/python/knot_resolver/manager/files/__init__.py new file mode 100644 index 00000000..49700656 --- /dev/null +++ b/python/knot_resolver/manager/files/__init__.py @@ -0,0 +1,3 @@ +from .watchdog import init_files_watchdog + +__all__ = ["init_files_watchdog"] diff --git a/python/knot_resolver/manager/files/watchdog.py b/python/knot_resolver/manager/files/watchdog.py new file mode 100644 index 00000000..9cb644a6 --- /dev/null +++ b/python/knot_resolver/manager/files/watchdog.py @@ -0,0 +1,88 @@ +import importlib +import logging +from pathlib import Path +from typing import List, Optional, Union + +from knot_resolver.controller.registered_workers import command_registered_workers +from knot_resolver.datamodel import KresConfig +from knot_resolver.datamodel.types import File +from knot_resolver.manager.config_store import ConfigStore, only_on_real_changes_update +from knot_resolver.utils import compat + +_watchdog = False +if importlib.util.find_spec("watchdog"): + _watchdog = True + +logger = logging.getLogger(__name__) + + +def files_to_watch(config: KresConfig) -> List[Path]: + files: List[Optional[File]] = [ + config.network.tls.cert_file, + config.network.tls.key_file, + ] + return [file.to_path() for file in files if file is not None] + + +if _watchdog: + from watchdog.events import ( + DirModifiedEvent, + FileModifiedEvent, + FileSystemEventHandler, + ) + from watchdog.observers import Observer + + _files_watchdog: Optional["FilesWatchDog"] = None + + class CertificatesEventHandler(FileSystemEventHandler): + + def __init__(self, config: KresConfig) -> None: + self._config = config + self._command = f"net.tls('{config.network.tls.cert_file}', '{config.network.tls.key_file}')" + + # def on_any_event(self, event: FileSystemEvent) -> None: + # pass + + # def on_created(self, event: Union[DirCreatedEvent, FileCreatedEvent]) -> None: + # pass + + # def on_deleted(self, event: Union[DirDeletedEvent, FileDeletedEvent]) -> None: + # pass + + def on_modified(self, event: Union[DirModifiedEvent, FileModifiedEvent]) -> None: + if compat.asyncio.is_event_loop_running(): + compat.asyncio.create_task(command_registered_workers(self._command)) + else: + compat.asyncio.run(command_registered_workers(self._command)) + + # def on_closed(self, event: FileClosedEvent) -> None: + # pass + + class FilesWatchDog: + def __init__(self, config: KresConfig, files: List[Path]) -> None: + self._observer = Observer() + for file in files: + self._observer.schedule(CertificatesEventHandler(config), str(file), recursive=False) + logger.info(f"Watching '{file}. file") + + def start(self) -> None: + if self._observer: + self._observer.start() + + def stop(self) -> None: + if self._observer: + self._observer.stop() + self._observer.join() + + @only_on_real_changes_update(files_to_watch) + async def _init_files_watchdog(config: KresConfig) -> None: + global _files_watchdog + if _files_watchdog is None: + logger.info("Starting files WatchDog") + _files_watchdog = FilesWatchDog(config, files_to_watch(config)) + _files_watchdog.start() + + +async def init_files_watchdog(config_store: ConfigStore) -> None: + if _watchdog: + await config_store.register_on_change_callback(_init_files_watchdog) diff --git a/python/knot_resolver/manager/server.py b/python/knot_resolver/manager/server.py index 90fd4d3b..fbfef244 100644 --- a/python/knot_resolver/manager/server.py +++ b/python/knot_resolver/manager/server.py @@ -27,7 +27,7 @@ from knot_resolver.datamodel.cache_schema import CacheClearRPCSchema from knot_resolver.datamodel.config_schema import KresConfig, get_rundir_without_validation from knot_resolver.datamodel.globals import Context, set_global_validation_context from knot_resolver.datamodel.management_schema import ManagementSchema -from knot_resolver.manager import metrics +from knot_resolver.manager import files, metrics from knot_resolver.utils import custom_atexit as atexit from knot_resolver.utils import ignore_exceptions_optional from knot_resolver.utils.async_utils import readfile @@ -566,6 +566,8 @@ async def start_server(config: Path = CONFIG_FILE) -> int: # noqa: PLR0915 # started, therefore before initializing manager await metrics.init_prometheus(config_store) + await files.init_files_watchdog(config_store) + # prepare instance of the server (no side effects) server = Server(config_store, config) |