This commit is contained in:
Mateusz Gruszczyński
2025-09-05 09:48:41 +02:00
parent 3947e590d6
commit 04d5a514b4
2 changed files with 11 additions and 13 deletions

17
app.py
View File

@@ -200,27 +200,29 @@ def validateHostsSyntax(hosts_content):
seen[key] = True seen[key] = True
return None return None
def writeHostsAtomic(new_content: str, path: str = "/etc/hosts", backup_dir: str | None = None) -> dict: def writeHostsAtomic(new_content: str, path: str = "/etc/hosts") -> dict:
""" """
Zapisuje plik atomowo: Zapisuje plik atomowo:
- tworzy kopię zapasową (z timestampem) jeśli backup_dir podane, - tworzy kopię zapasową w katalogu z config.ini (klucz backup_path),
- zapis do pliku tymczasowego + fsync + rename(), - zapis do pliku tymczasowego + fsync + rename(),
- ustawia chmod 644 na docelowym pliku. - ustawia chmod 644 na docelowym pliku.
Zwraca info o backupie i ścieżkach.
""" """
from tempfile import NamedTemporaryFile from tempfile import NamedTemporaryFile
info = {"path": path, "backup": None} info = {"path": path, "backup": None}
backup_dir = getCfg("backup_path", None)
# kopia zapasowa # kopia zapasowa
if backup_dir: if backup_dir:
os.makedirs(backup_dir, exist_ok=True) os.makedirs(backup_dir, exist_ok=True)
ts = datetime.now(timezone.utc).strftime("%Y%m%dT%H%M%SZ")
dest_path = os.path.join(backup_dir, f"hosts.{ts}.bak")
try: try:
shutil.copy2(path, backup_path) shutil.copy2(path, dest_path)
info["backup"] = backup_path info["backup"] = dest_path
except Exception as e: except Exception as e:
logger.warning(f"Backup nieudany: {e}") logger.warning(f"Backup nieudany: {e}")
# zapis atomowy # zapis atomowy
dir_name = os.path.dirname(path) or "." dir_name = os.path.dirname(path) or "."
with NamedTemporaryFile("w", dir=dir_name, delete=False, encoding="utf-8") as tmp: with NamedTemporaryFile("w", dir=dir_name, delete=False, encoding="utf-8") as tmp:
@@ -230,7 +232,7 @@ def writeHostsAtomic(new_content: str, path: str = "/etc/hosts", backup_dir: str
tmp_name = tmp.name tmp_name = tmp.name
os.replace(tmp_name, path) os.replace(tmp_name, path)
# ustaw poprawne prawa # ustaw chmod 644
try: try:
os.chmod(path, 0o644) os.chmod(path, 0o644)
except Exception as e: except Exception as e:
@@ -238,6 +240,7 @@ def writeHostsAtomic(new_content: str, path: str = "/etc/hosts", backup_dir: str
return info return info
def computeUnifiedDiff(old_text: str, new_text: str, fromfile="/etc/hosts(old)", tofile="/etc/hosts(new)") -> str: def computeUnifiedDiff(old_text: str, new_text: str, fromfile="/etc/hosts(old)", tofile="/etc/hosts(new)") -> str:
import difflib import difflib
return "".join(difflib.unified_diff( return "".join(difflib.unified_diff(

View File

@@ -1,16 +1,11 @@
[daemon] [daemon]
API_TOKEN = apitoken API_TOKEN = apitoken
backup_path = /backup backup_path = /backup
services = dnsmasq services = dnsmasq
# opcjonalnie: globalny timeout (sekundy) # opcjonalnie: globalny timeout (sekundy)
reload_timeout = 5 reload_timeout = 5
# jeżeli nie podasz command, kod spróbuje kolejno: systemctl/service/rc-service, pkill, kill -HUP z pidfile, pgrep # jeżeli nie podasz command, kod spróbuje kolejno: systemctl/service/rc-service, pkill, kill -HUP z pidfile, pgrep
pid_file = /run/dnsmasq/dnsmasq.pid
[service:dnsmasq] [service:dnsmasq]
# jeśli systemctl nie działa: # jeśli systemctl nie działa:
# command = rc-service dnsmasq reload # command = rc-service dnsmasq reload