feat(core): implement modular OOP engine following SOLID and DRY principles
- models: DomainConfig, ServiceConfig, DiagnosticReport (single source of truth) - interfaces: DIP & ISP contracts for detector, generator, executor, doctor, and migrator - detector: Smart auto-detection for modular (config/wsgi.py), traditional, and flat layouts - service_generator: Systemd service generation with --umask 007 and security sandboxing - executor: Linux command execution with dry-run support - nginx_manager: HestiaCP template installation and validation - migrator: Automated migration and repair of existing deployments - doctor: Comprehensive post-deployment health check engine
This commit is contained in:
59
core/nginx_manager.py
Normal file
59
core/nginx_manager.py
Normal file
@@ -0,0 +1,59 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
NGINX template manager for HestiaCP.
|
||||
|
||||
**Single Responsibility:** Install, validate, and manage the custom NGINX
|
||||
proxy templates that HestiaCP uses to route traffic to the Gunicorn socket.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from core.interfaces import INginxManager, ISystemExecutor
|
||||
from core.models import HESTIA_TEMPLATE_DIR, TEMPLATE_NAME, DomainConfig
|
||||
|
||||
|
||||
class HestiaNginxManager(INginxManager):
|
||||
"""Manages NGINX template deployment for HestiaCP."""
|
||||
|
||||
def __init__(self, executor: ISystemExecutor) -> None:
|
||||
self._executor = executor
|
||||
|
||||
@property
|
||||
def tpl_dest(self) -> Path:
|
||||
return HESTIA_TEMPLATE_DIR / f"{TEMPLATE_NAME}.tpl"
|
||||
|
||||
@property
|
||||
def stpl_dest(self) -> Path:
|
||||
return HESTIA_TEMPLATE_DIR / f"{TEMPLATE_NAME}.stpl"
|
||||
|
||||
def install_templates(self, tpl_source: Path, stpl_source: Path) -> None:
|
||||
"""Copy templates to the HestiaCP template directory and set permissions."""
|
||||
for src, dst in [(tpl_source, self.tpl_dest), (stpl_source, self.stpl_dest)]:
|
||||
if not self._executor.file_exists(src):
|
||||
raise FileNotFoundError(f"Template source not found: {src}")
|
||||
|
||||
content = src.read_text(encoding="utf-8")
|
||||
self._executor.write_file(dst, content, mode=0o644)
|
||||
|
||||
# Set ownership to root:root
|
||||
self._executor.run(
|
||||
f"chown root:root {self.tpl_dest} {self.stpl_dest}"
|
||||
)
|
||||
|
||||
def rebuild_domain(self, domain_config: DomainConfig) -> None:
|
||||
"""Force-rebuild the NGINX configuration for a domain and restart."""
|
||||
dc = domain_config
|
||||
self._executor.run(
|
||||
f"v-rebuild-web-domain {dc.user} {dc.domain} yes",
|
||||
check=False,
|
||||
)
|
||||
self._executor.run("systemctl restart nginx", check=False)
|
||||
|
||||
def is_template_installed(self) -> bool:
|
||||
"""Check if both template files exist in the HestiaCP directory."""
|
||||
return (
|
||||
self._executor.file_exists(self.tpl_dest)
|
||||
and self._executor.file_exists(self.stpl_dest)
|
||||
)
|
||||
Reference in New Issue
Block a user