mirror of
https://github.com/netinvent/npbackup.git
synced 2025-09-12 07:55:23 +08:00
Merge branch 'main' of https://github.com/netinvent/npbackup
This commit is contained in:
commit
34e03dbce1
7 changed files with 72 additions and 7 deletions
|
@ -7,7 +7,7 @@ __intname__ = "npbackup.configuration"
|
||||||
__author__ = "Orsiris de Jong"
|
__author__ = "Orsiris de Jong"
|
||||||
__copyright__ = "Copyright (C) 2022-2024 NetInvent"
|
__copyright__ = "Copyright (C) 2022-2024 NetInvent"
|
||||||
__license__ = "GPL-3.0-only"
|
__license__ = "GPL-3.0-only"
|
||||||
__build__ = "2024090601"
|
__build__ = "2024110701"
|
||||||
__version__ = "npbackup 3.0.0+"
|
__version__ = "npbackup 3.0.0+"
|
||||||
|
|
||||||
MIN_CONF_VERSION = 3.0
|
MIN_CONF_VERSION = 3.0
|
||||||
|
@ -78,7 +78,13 @@ def g(self, path, sep=".", default=None, list_ok=False):
|
||||||
Getter for dot notation in an a dict/OrderedDict
|
Getter for dot notation in an a dict/OrderedDict
|
||||||
print(d.g('my.array.keys'))
|
print(d.g('my.array.keys'))
|
||||||
"""
|
"""
|
||||||
return self.mlget(path.split(sep), default=default, list_ok=list_ok)
|
try:
|
||||||
|
return self.mlget(path.split(sep), default=default, list_ok=list_ok)
|
||||||
|
except AssertionError as exc:
|
||||||
|
logger.debug(
|
||||||
|
f"ERROR {exc} for path={path},sep={sep},default={default},list_ok={list_ok}"
|
||||||
|
)
|
||||||
|
raise AssertionError
|
||||||
|
|
||||||
|
|
||||||
def s(self, path, value, sep="."):
|
def s(self, path, value, sep="."):
|
||||||
|
@ -203,6 +209,9 @@ empty_config_dict = {
|
||||||
"yearly": 3,
|
"yearly": 3,
|
||||||
"tags": [],
|
"tags": [],
|
||||||
"keep_within": True,
|
"keep_within": True,
|
||||||
|
"group_by_host": True,
|
||||||
|
"group_by_tags": True,
|
||||||
|
"group_by_paths": False,
|
||||||
"ntp_server": None,
|
"ntp_server": None,
|
||||||
},
|
},
|
||||||
# "prune_max_unused": None, # TODO
|
# "prune_max_unused": None, # TODO
|
||||||
|
|
|
@ -7,7 +7,7 @@ __intname__ = "npbackup.gui.core.runner"
|
||||||
__author__ = "Orsiris de Jong"
|
__author__ = "Orsiris de Jong"
|
||||||
__copyright__ = "Copyright (C) 2022-2024 NetInvent"
|
__copyright__ = "Copyright (C) 2022-2024 NetInvent"
|
||||||
__license__ = "GPL-3.0-only"
|
__license__ = "GPL-3.0-only"
|
||||||
__build__ = "2024110301"
|
__build__ = "2024110701"
|
||||||
|
|
||||||
|
|
||||||
from typing import Optional, Callable, Union, List
|
from typing import Optional, Callable, Union, List
|
||||||
|
@ -1444,10 +1444,17 @@ class NPBackupRunner:
|
||||||
msg = f"Empty retention policy. Won't run"
|
msg = f"Empty retention policy. Won't run"
|
||||||
self.write_logs(msg, level="error")
|
self.write_logs(msg, level="error")
|
||||||
return self.convert_to_json_output(False, msg)
|
return self.convert_to_json_output(False, msg)
|
||||||
|
|
||||||
|
# Convert group by to list
|
||||||
|
group_by = []
|
||||||
|
for entry in ["host", "paths", "tags"]:
|
||||||
|
if self.repo_config.g(f"repo_opts.retention_policy.group_by_{entry}"):
|
||||||
|
group_by.append(entry)
|
||||||
|
|
||||||
self.write_logs(
|
self.write_logs(
|
||||||
f"Forgetting snapshots using retention policy: {policy}", level="info"
|
f"Forgetting snapshots using retention policy: {policy}", level="info"
|
||||||
)
|
)
|
||||||
result = self.restic_runner.forget(policy=policy)
|
result = self.restic_runner.forget(policy=policy, group_by=group_by)
|
||||||
else:
|
else:
|
||||||
self.write_logs(
|
self.write_logs(
|
||||||
"Bogus options given to forget: snapshots={snapshots}, policy={policy}",
|
"Bogus options given to forget: snapshots={snapshots}, policy={policy}",
|
||||||
|
|
|
@ -7,7 +7,7 @@ __intname__ = "npbackup.gui.config"
|
||||||
__author__ = "Orsiris de Jong"
|
__author__ = "Orsiris de Jong"
|
||||||
__copyright__ = "Copyright (C) 2022-2024 NetInvent"
|
__copyright__ = "Copyright (C) 2022-2024 NetInvent"
|
||||||
__license__ = "GPL-3.0-only"
|
__license__ = "GPL-3.0-only"
|
||||||
__build__ = "2024072301"
|
__build__ = "2024110701"
|
||||||
|
|
||||||
|
|
||||||
from typing import List, Tuple
|
from typing import List, Tuple
|
||||||
|
@ -1572,6 +1572,40 @@ def config_gui(full_config: dict, config_file: str):
|
||||||
size=(100, 1),
|
size=(100, 1),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
[sg.Text(_t("config_gui.policiy_group_by"))],
|
||||||
|
[
|
||||||
|
sg.Image(
|
||||||
|
NON_INHERITED_ICON,
|
||||||
|
key="inherited.repo_opts.retention_policy.group_by_host",
|
||||||
|
tooltip=_t("config_gui.group_inherited"),
|
||||||
|
pad=1,
|
||||||
|
),
|
||||||
|
sg.Checkbox(
|
||||||
|
_t("config_gui.group_by_host"),
|
||||||
|
key="repo_opts.retention_policy.group_by_host",
|
||||||
|
),
|
||||||
|
sg.Image(
|
||||||
|
NON_INHERITED_ICON,
|
||||||
|
key="inherited.repo_opts.retention_policy.group_by_paths",
|
||||||
|
tooltip=_t("config_gui.group_inherited"),
|
||||||
|
pad=1,
|
||||||
|
),
|
||||||
|
sg.Checkbox(
|
||||||
|
_t("config_gui.group_by_paths"),
|
||||||
|
key="repo_opts.retention_policy.group_by_paths",
|
||||||
|
),
|
||||||
|
sg.Image(
|
||||||
|
NON_INHERITED_ICON,
|
||||||
|
key="inherited.repo_opts.retention_policy.group_by_tags",
|
||||||
|
tooltip=_t("config_gui.group_inherited"),
|
||||||
|
pad=1,
|
||||||
|
),
|
||||||
|
sg.Checkbox(
|
||||||
|
_t("config_gui.group_by_tags"),
|
||||||
|
key="repo_opts.retention_policy.group_by_tags",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
[sg.Text(_t("config_gui.policiy_group_by_explanation"))],
|
||||||
[sg.HorizontalSeparator()],
|
[sg.HorizontalSeparator()],
|
||||||
[
|
[
|
||||||
sg.Column(
|
sg.Column(
|
||||||
|
|
|
@ -1089,6 +1089,7 @@ class ResticRunner:
|
||||||
self,
|
self,
|
||||||
snapshots: Optional[Union[List[str], Optional[str]]] = None,
|
snapshots: Optional[Union[List[str], Optional[str]]] = None,
|
||||||
policy: Optional[dict] = None,
|
policy: Optional[dict] = None,
|
||||||
|
group_by: Optional[List[str]] = None,
|
||||||
) -> Union[bool, str, dict]:
|
) -> Union[bool, str, dict]:
|
||||||
"""
|
"""
|
||||||
Execute forget command for given snapshot
|
Execute forget command for given snapshot
|
||||||
|
@ -1119,6 +1120,8 @@ class ResticRunner:
|
||||||
cmd += f" --keep-tag {tag}"
|
cmd += f" --keep-tag {tag}"
|
||||||
else:
|
else:
|
||||||
cmd += f" --{key.replace('_', '-')} {value}"
|
cmd += f" --{key.replace('_', '-')} {value}"
|
||||||
|
if group_by:
|
||||||
|
cmd += f' --group-by {",".join(group_by)}'
|
||||||
cmds = [cmd]
|
cmds = [cmd]
|
||||||
|
|
||||||
# We need to be verbose here since server errors will not stop client from deletion attempts
|
# We need to be verbose here since server errors will not stop client from deletion attempts
|
||||||
|
|
|
@ -162,4 +162,10 @@ en:
|
||||||
enter_label_value: Enter label value
|
enter_label_value: Enter label value
|
||||||
enter_labvel: Enter label
|
enter_labvel: Enter label
|
||||||
|
|
||||||
suggested_encrypted_env_variables: Suggested encrypted environment variables
|
suggested_encrypted_env_variables: Suggested encrypted environment variables
|
||||||
|
|
||||||
|
policiy_group_by: Apply retention policy by grouping snapshots
|
||||||
|
group_by_host: Group by host
|
||||||
|
group_by_paths: Group by paths
|
||||||
|
group_by_tags: Group by tags
|
||||||
|
policiy_group_by_explanation: If none are chosen, snapshots will be grouped by host and paths
|
|
@ -163,4 +163,10 @@ fr:
|
||||||
enter_label_value: Entrer la valeur de l'étiquette
|
enter_label_value: Entrer la valeur de l'étiquette
|
||||||
enter_label: Entrer étiquette
|
enter_label: Entrer étiquette
|
||||||
|
|
||||||
suggested_encrypted_env_variables: Variables chiffrées suggérées
|
suggested_encrypted_env_variables: Variables chiffrées suggérées
|
||||||
|
|
||||||
|
policiy_group_by: Appliquer la politique de rétention par groupes d'instantanés
|
||||||
|
group_by_host: Grouper par nom d'hôte
|
||||||
|
group_by_paths: Grouper par chemins sauvegardés
|
||||||
|
group_by_tags: Grouper par tags
|
||||||
|
policiy_group_by_explanation: Si aucun groupement n'est choisi, le groupement par nom d'hôte et chemin de sauvegarde sera utilisé
|
Loading…
Add table
Reference in a new issue