--- /dev/null
+from __future__ import annotations
+
+from pathlib import Path
+
+from jinja2 import Environment, FileSystemLoader, StrictUndefined, Template
+
+
+def _get_templates_path() -> Path:
+ templates_path = Path(__file__).resolve().parent
+ if not templates_path.exists():
+ raise FileNotFoundError(templates_path)
+ if not templates_path.is_dir():
+ raise NotADirectoryError(templates_path)
+ return templates_path
+
+
+_TEMPLATES_PATH: Path = _get_templates_path()
+
+
+def _load_template_from_str(template: str) -> Template:
+ loader = FileSystemLoader(_TEMPLATES_PATH)
+ env = Environment(trim_blocks=True, lstrip_blocks=True, loader=loader, undefined=StrictUndefined)
+ return env.from_string(template)
+
+
+def _import_template(template: str) -> Template:
+ template_file = _TEMPLATES_PATH / template
+ with template_file.open() as file:
+ template = file.read()
+ return _load_template_from_str(template)
+
+
+SUPERVISORD_TEMPLATE: Template = _import_template("supervisord.conf.j2")
--- /dev/null
+[supervisord]
+directory = {{ supervisord.workdir }}
+pidfile = {{ supervisord.pidfile }}
+logfile = {{ supervisord.logfile }}
+logfile_maxbytes = 0
+loglevel = {{ supervisord.loglevel }}
+nodaemon = true
+silent = true
+
+[supervisorctl]
+serverurl = unix://{{ supervisord.unix_http_server }}
+
+[unix_http_server]
+file = {{ supervisord.unix_http_server }}
+
+[program:manager]
+command = {{ manager.command }}
+directory = {{ manager.workdir }}
+environment = {{ manager.environment }}
+startsecs= {{ manager.startsecs }}
+redirect_stderr = false
+autostart = true
+autorestart = true
+killasgroup = true
+stopsignal = SIGTERM
+stopwaitsecs = 30
+stdout_logfile = NONE
+stderr_logfile = NONE
+
+[program:worker]
+process_name = %(program_name)s%(process_num)d
+numprocs = {{ worker.max_procs }}
+command = {{ worker.command }}
+directory = {{ worker.workdir }}
+environment = {{ worker.environment }}
+startsecs = {{ worker.startsecs }}
+redirect_stderr = false
+autostart = false
+autorestart = true
+killasgroup = true
+stopsignal = SIGTERM
+stopwaitsecs = 30
+stdout_logfile = NONE
+stderr_logfile = NONE
+
+[program:loader]
+command = {{ loader.command }}
+directory = {{ loader.workdir }}
+environment = {{ loader.environment }}
+startsecs = {{ loader.startsecs }}
+redirect_stderr = false
+autostart = false
+exitcodes = 0
+killasgroup = true
+stopsignal = SIGTERM
+stopwaitsecs = 30
+stdout_logfile = NONE
+stderr_logfile = NONE
+
+[program:cache-gc]
+command = {{ cache_gc.command }}
+directory = {{ cache_gc.workdir }}
+environment = {{ cache_gc.environment }}
+startsecs={{ cache_gc.startsecs }}
+redirect_stderr=false
+autostart=false
+autorestart=true
+killasgroup=true
+stopsignal = SIGTERM
+stopwaitsecs = 30
+stdout_logfile=NONE
+stderr_logfile=NONE
['knot_resolver',
'knot_resolver.client',
'knot_resolver.config',
+ 'knot_resolver.config.templates',
'knot_resolver.controller',
'knot_resolver.manager',
'knot_resolver.utils']