diff --git a/CHANGELOG b/CHANGELOG index 88aec22..17c54d9 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -6,13 +6,12 @@ - with button to select forget/prune operation - With explanation link to restic - prune operation: default max unsed ? - - Operation planifier: + - Operation planifier - backups - cleaner (forget / check / prune, each having different planification (at least for check --read-data)) - Launch now - NPBackup Operation mode - manages multiple repos with generic key (restic key add) or specified key - !- NTP server - GUI --help parameter should intercept stdout and show results in a popup @@ -37,7 +36,9 @@ !- Operation center - GUI operation center allowing to mass execute actions on repos / groups - CLI operation center via `--group-operation --repo-group=somegroup` - !- Implemented retention policies + - Implemented retention policies + - Optional time server update to make sure we don't drift before doing retention operations + ! Optional repo check before doing retention operations !- Operation planifier allows to create scheduled tasks for operations !- Implemented scheduled task creator for Windows & Unix !(simple list of tasks, actions, stop on error) @@ -71,6 +72,7 @@ - Allow a 30 seconds grace period for child processes to close before asking them nicely, and than not nicely to quit - Fully refactored prometheus metrics parser to be able to read restic standard or json outputs - Reimplmented auto upgrade after CLI/GUI split + - --dry-run now works with other commands than backup - Added initial tests ## 2.2.2 - 14/12/2023 (internal build only) @@ -189,7 +191,7 @@ - Fix error message in logs when repo is not initialized ## v2.2.0 - rc1 - 02/02/2023 - - Added a full auto-upgrade solution: + - Added a full auto-upgrade solution - Aupgrade client integrated into NPBackup, that can be called manually via --auto-upgrade or automatically run every n backups - Upgrade server which servers files and their metadata - Added a gui to create a scheduled task under Windows @@ -241,9 +243,9 @@ - Fix for ruamel.yaml global objects being modified out of current scope encrypting current config while saving - Fix npbackup could not start when no config file was present - Drastically improve ls operation speed by changing command_runner method from poller to monitor (no live output) except for backup operation - - Compiler: + - Compiler - Compile python 3.7 and 3.10 targets so we also get to use Windows 7 which can't run python > 3.7 - - Installer: + - Installer - Moved task creation process to npbackup so we can recreate tasks on systems where npbackup is already installed ## v1.8.0 @@ -266,7 +268,7 @@ - Allow setting additional prometheus labels - Fix gui snapshot contents don't show duplicate parents on Windows when backing up 'c:\foo' and 'C:\bar' - Internal code cleanup - - Installer: + - Installer - Make sure we don't overwrite destination configuration file if existing ## v1.5.3 diff --git a/npbackup/configuration.py b/npbackup/configuration.py index 3354656..5094a70 100644 --- a/npbackup/configuration.py +++ b/npbackup/configuration.py @@ -191,7 +191,7 @@ empty_config_dict = { "yearly": 3, "tags": [], "keep_within": True, - "ntp_time_server": None, # TODO + "ntp_server": None, }, # "prune_max_unused": None, # TODO # "prune_max_repack_size": None, # TODO diff --git a/npbackup/core/runner.py b/npbackup/core/runner.py index 76ca6ee..afb0dfa 100644 --- a/npbackup/core/runner.py +++ b/npbackup/core/runner.py @@ -24,6 +24,7 @@ from command_runner import command_runner from ofunctions.threading import threaded from ofunctions.platform import os_arch from ofunctions.misc import BytesConverter +import ntplib from npbackup.restic_metrics import ( restic_str_output_to_json, restic_json_to_prometheus, @@ -118,6 +119,21 @@ def metric_writer( return backup_too_small +def get_ntp_offset(ntp_server: str) -> Optional[float]: + """ + Get current time offset from ntp server + """ + try: + client = ntplib.NTPClient() + response = client.request(ntp_server) + return response.offset + except ntplib.NTPException as exc: + logger.error(f"Cannot get NTP offset from {ntp_server}: {exc}") + except Exception as exc: + logger.error(f"Cannot reach NTP server {ntp_server}: {exc}") + return None + + class NPBackupRunner: """ Wraps ResticRunner into a class that is usable by NPBackup @@ -1161,6 +1177,17 @@ class NPBackupRunner: self.write_logs(f"Forgetting snapshots {snapshots}", level="info") result = self.restic_runner.forget(snapshots) elif use_policy: + # Let's check if we can get a valid NTP server offset + # If offset is too big, we won't apply policy + # Offset should not be higher than 10 minutes, eg 600 seconds + ntp_server = self.repo_config.g("repo_opts.retention_policy.ntp_server") + if ntp_server: + offset = get_ntp_offset(ntp_server) + if not offset or offset >= 600: + msg = f"Offset from NTP server {ntp_server} is too high: {int(offset)} seconds. Won't apply policy" + self.write_logs(msg, level="critical") + return self.convert_to_json_output(False, msg) + # Build policiy from config policy = {} for entry in ["last", "hourly", "daily", "weekly", "monthly", "yearly"]: diff --git a/npbackup/gui/config.py b/npbackup/gui/config.py index 903bcb3..4b92ed4 100644 --- a/npbackup/gui/config.py +++ b/npbackup/gui/config.py @@ -1325,7 +1325,7 @@ def config_gui(full_config: dict, config_file: str): [ sg.Text(_t("config_gui.optional_ntp_server_uri"), size=(40, 1)), sg.Input( - key="repo_opts.retention_policy.ntp_time_server", size=(50, 1) + key="repo_opts.retention_policy.ntp_server", size=(50, 1) ), ], ] diff --git a/npbackup/requirements.txt b/npbackup/requirements.txt index 7648986..4f52884 100644 --- a/npbackup/requirements.txt +++ b/npbackup/requirements.txt @@ -25,3 +25,4 @@ i18nice>=0.6.2 packaging pywin32; platform_system == "Windows" imageio; platform_system == "Darwin" +ntplib>=0.4.0 diff --git a/npbackup/translations/config_gui.en.yml b/npbackup/translations/config_gui.en.yml index 4081f16..c0c1791 100644 --- a/npbackup/translations/config_gui.en.yml +++ b/npbackup/translations/config_gui.en.yml @@ -120,7 +120,7 @@ en: keep_within: Keep within keep_within_explanation: Keep only the last n snapshots within the last m snapshots keep_tags: Keep snapshots with the following tags - optional_ntp_server_uri: Optional NTP server URL + optional_ntp_server_uri: Optional NTP server URI # repo / group managmeent repo_group: Repo group