Aggiunge notifier server per scheduler
This commit is contained in:
@@ -46,6 +46,7 @@ class StorageConfig:
|
||||
change_registry: Path
|
||||
logs_dir: Path
|
||||
status_file: Path
|
||||
notifier_state_file: Path
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@@ -104,11 +105,11 @@ def save_config_data(data: dict[str, Any], path: Path | None = None) -> Path:
|
||||
|
||||
|
||||
def migrate_config_data(data: dict[str, Any]) -> bool:
|
||||
changed = _migrate_storage_config(data)
|
||||
backup = data.get("backup")
|
||||
if not isinstance(backup, dict):
|
||||
return False
|
||||
return changed
|
||||
|
||||
changed = False
|
||||
engine = str(backup.get("engine", "robocopy")).lower()
|
||||
if "engine" not in backup:
|
||||
backup["engine"] = engine
|
||||
@@ -138,6 +139,16 @@ def migrate_config_data(data: dict[str, Any]) -> bool:
|
||||
return changed
|
||||
|
||||
|
||||
def _migrate_storage_config(data: dict[str, Any]) -> bool:
|
||||
storage = data.get("storage")
|
||||
if not isinstance(storage, dict):
|
||||
return False
|
||||
if "notifier_state_file" in storage:
|
||||
return False
|
||||
storage["notifier_state_file"] = "%PROGRAMDATA%\\BakRest\\notifier-state.json"
|
||||
return True
|
||||
|
||||
|
||||
def parse_config(data: dict[str, Any], path: Path) -> AppConfig:
|
||||
service = data.get("service", {})
|
||||
tray = data.get("tray", {})
|
||||
@@ -159,6 +170,9 @@ def parse_config(data: dict[str, Any], path: Path) -> AppConfig:
|
||||
),
|
||||
logs_dir=expand_path(storage.get("logs_dir", "%PROGRAMDATA%\\BakRest\\logs")),
|
||||
status_file=expand_path(storage.get("status_file", "%PROGRAMDATA%\\BakRest\\status.json")),
|
||||
notifier_state_file=expand_path(
|
||||
storage.get("notifier_state_file", "%PROGRAMDATA%\\BakRest\\notifier-state.json")
|
||||
),
|
||||
)
|
||||
|
||||
return AppConfig(
|
||||
|
||||
@@ -69,4 +69,5 @@ unchanged_checks_required = 2
|
||||
change_registry = "%PROGRAMDATA%\\\\BakRest\\\\changes.sqlite"
|
||||
logs_dir = "%PROGRAMDATA%\\\\BakRest\\\\logs"
|
||||
status_file = "%PROGRAMDATA%\\\\BakRest\\\\status.json"
|
||||
notifier_state_file = "%PROGRAMDATA%\\\\BakRest\\\\notifier-state.json"
|
||||
"""
|
||||
|
||||
83
src/bakrest/server_notifier.py
Normal file
83
src/bakrest/server_notifier.py
Normal file
@@ -0,0 +1,83 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import tkinter as tk
|
||||
from pathlib import Path
|
||||
from tkinter import messagebox
|
||||
|
||||
from .config import load_config
|
||||
from .logging_setup import close_logger, configure_logging
|
||||
from .registry import ChangeRegistry
|
||||
from .server_check import ServerStatus, check_server, write_status
|
||||
|
||||
|
||||
ALERT_MESSAGE = "Accendi il server di backup o verifica che sia connesso alla rete"
|
||||
|
||||
|
||||
def run_server_notifier(always_alert: bool = False) -> int:
|
||||
config = load_config()
|
||||
logger = configure_logging(config.storage.logs_dir, "server-notifier")
|
||||
try:
|
||||
status = check_server(config.backup)
|
||||
pending_count = ChangeRegistry(config.storage.change_registry).pending_count()
|
||||
write_status(config.storage.status_file, status, pending_count)
|
||||
|
||||
if status.reachable:
|
||||
logger.info("Backup server reachable")
|
||||
_write_state(config.storage.notifier_state_file, "reachable")
|
||||
return 0
|
||||
|
||||
logger.warning("Backup server unreachable: %s", status.message)
|
||||
previous_state = _read_state(config.storage.notifier_state_file)
|
||||
if always_alert or previous_state != "unreachable":
|
||||
_show_error_message("Bak&Rest", ALERT_MESSAGE)
|
||||
_write_state(config.storage.notifier_state_file, "unreachable")
|
||||
return 20
|
||||
finally:
|
||||
close_logger(logger)
|
||||
|
||||
|
||||
def should_alert(status: ServerStatus, previous_state: str | None, always_alert: bool = False) -> bool:
|
||||
if status.reachable:
|
||||
return False
|
||||
return always_alert or previous_state != "unreachable"
|
||||
|
||||
|
||||
def _read_state(path: Path) -> str | None:
|
||||
try:
|
||||
data = json.loads(path.read_text(encoding="utf-8"))
|
||||
except (OSError, json.JSONDecodeError):
|
||||
return None
|
||||
state = data.get("server_state")
|
||||
return str(state) if state else None
|
||||
|
||||
|
||||
def _write_state(path: Path, state: str) -> None:
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
path.write_text(json.dumps({"server_state": state}, indent=2), encoding="utf-8")
|
||||
|
||||
|
||||
def _show_error_message(title: str, message: str) -> None:
|
||||
root = tk.Tk()
|
||||
root.withdraw()
|
||||
root.attributes("-topmost", True)
|
||||
try:
|
||||
messagebox.showerror(title, message, parent=root)
|
||||
finally:
|
||||
root.destroy()
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(description="Notify the user if the backup server is unreachable")
|
||||
parser.add_argument(
|
||||
"--always-alert",
|
||||
action="store_true",
|
||||
help="Show the warning even if it was already shown while the server was down",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
return run_server_notifier(always_alert=args.always_alert)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Reference in New Issue
Block a user