mirror of
https://github.com/netinvent/npbackup.git
synced 2024-09-20 14:56:14 +08:00
Implement repair pack command
This commit is contained in:
parent
3e72ac4c1b
commit
0fdda44197
|
@ -156,6 +156,12 @@ This is free software, and you are welcome to redistribute it under certain cond
|
||||||
)
|
)
|
||||||
parser.add_argument("--unlock", action="store_true", help="Unlock repository")
|
parser.add_argument("--unlock", action="store_true", help="Unlock repository")
|
||||||
parser.add_argument("--repair-index", action="store_true", help="Repair repo index")
|
parser.add_argument("--repair-index", action="store_true", help="Repair repo index")
|
||||||
|
parser.add_argument(
|
||||||
|
"--repair-packs",
|
||||||
|
default=None,
|
||||||
|
required=False,
|
||||||
|
help="Repair repo packs ids given by --repair-packs",
|
||||||
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--repair-snapshots", action="store_true", help="Repair repo snapshots"
|
"--repair-snapshots", action="store_true", help="Repair repo snapshots"
|
||||||
)
|
)
|
||||||
|
@ -270,7 +276,7 @@ This is free software, and you are welcome to redistribute it under certain cond
|
||||||
type=str,
|
type=str,
|
||||||
default=None,
|
default=None,
|
||||||
required=False,
|
required=False,
|
||||||
help="Launch an operation on a group of repositories given by --repo-group or --repo-name. Valid group operations are [backup|restore|snapshots|list|ls|find|policy|quick_check|full_check|prune|prune_max|unlock|repair_index|repair_snapshots|dump|stats|raw|has_recent_snapshot]",
|
help="Launch an operation on a group of repositories given by --repo-group or --repo-name. Valid group operations are [backup|restore|snapshots|list|ls|find|policy|quick_check|full_check|prune|prune_max|unlock|repair_index|repair_packs|repair_snapshots|dump|stats|raw|has_recent_snapshot]",
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--create-key",
|
"--create-key",
|
||||||
|
@ -539,6 +545,12 @@ This is free software, and you are welcome to redistribute it under certain cond
|
||||||
elif args.repair_index or args.group_operation == "repair_index":
|
elif args.repair_index or args.group_operation == "repair_index":
|
||||||
cli_args["operation"] = "repair"
|
cli_args["operation"] = "repair"
|
||||||
cli_args["op_args"] = {"subject": "index"}
|
cli_args["op_args"] = {"subject": "index"}
|
||||||
|
elif args.repair_packs or args.group_operation == "repair_packs":
|
||||||
|
cli_args["operation"] = "repair"
|
||||||
|
cli_args["op_args"] = {
|
||||||
|
"subject": "packs",
|
||||||
|
"pack_ids": args.repair_packs,
|
||||||
|
}
|
||||||
elif args.repair_snapshots or args.group_operation == "repair_snapshots":
|
elif args.repair_snapshots or args.group_operation == "repair_snapshots":
|
||||||
cli_args["operation"] = "repair"
|
cli_args["operation"] = "repair"
|
||||||
cli_args["op_args"] = {"subject": "snapshots"}
|
cli_args["op_args"] = {"subject": "snapshots"}
|
||||||
|
@ -572,6 +584,7 @@ This is free software, and you are welcome to redistribute it under certain cond
|
||||||
"prune_max",
|
"prune_max",
|
||||||
"unlock",
|
"unlock",
|
||||||
"repair_index",
|
"repair_index",
|
||||||
|
"repair_packs",
|
||||||
"repair_snapshots",
|
"repair_snapshots",
|
||||||
"dump",
|
"dump",
|
||||||
"stats",
|
"stats",
|
||||||
|
@ -579,7 +592,7 @@ This is free software, and you are welcome to redistribute it under certain cond
|
||||||
"has_recent_snapshot",
|
"has_recent_snapshot",
|
||||||
):
|
):
|
||||||
logger.critical(
|
logger.critical(
|
||||||
f"Invalid group operation {args.group_operation}. Valid operations are [backup|restore|snapshots|list|ls|find|policy|housekeeping|quick_check|full_check|prune|prune_max|unlock|repair_index|repair_snapshots|dump|stats|raw|has_recent_snapshot]"
|
f"Invalid group operation {args.group_operation}. Valid operations are [backup|restore|snapshots|list|ls|find|policy|housekeeping|quick_check|full_check|prune|prune_max|unlock|repair_index|repair_packs|repair_snapshots|dump|stats|raw|has_recent_snapshot]"
|
||||||
)
|
)
|
||||||
sys.exit(74)
|
sys.exit(74)
|
||||||
repo_config_list = []
|
repo_config_list = []
|
||||||
|
|
|
@ -1431,11 +1431,11 @@ class NPBackupRunner:
|
||||||
@has_permission
|
@has_permission
|
||||||
@is_ready
|
@is_ready
|
||||||
@apply_config_to_restic_runner
|
@apply_config_to_restic_runner
|
||||||
def repair(self, subject: str) -> bool:
|
def repair(self, subject: str, pack_ids: str = None) -> bool:
|
||||||
self.write_logs(
|
self.write_logs(
|
||||||
f"Repairing {subject} in repo {self.repo_config.g('name')}", level="info"
|
f"Repairing {subject} in repo {self.repo_config.g('name')}", level="info"
|
||||||
)
|
)
|
||||||
return self.restic_runner.repair(subject)
|
return self.restic_runner.repair(subject, pack_ids)
|
||||||
|
|
||||||
@threaded
|
@threaded
|
||||||
@catch_exceptions
|
@catch_exceptions
|
||||||
|
|
|
@ -169,7 +169,9 @@ def operations_gui(full_config: dict) -> dict:
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
sg.Button(
|
sg.Button(
|
||||||
_t("operations_gui.unlock"), key="--UNLOCK--", size=(45, 1)
|
_t("operations_gui.repair_packs"),
|
||||||
|
key="--REPAIR-PACKS--",
|
||||||
|
size=(45, 1),
|
||||||
),
|
),
|
||||||
sg.Button(
|
sg.Button(
|
||||||
_t("operations_gui.forget_using_retention_policy"),
|
_t("operations_gui.forget_using_retention_policy"),
|
||||||
|
@ -190,11 +192,14 @@ def operations_gui(full_config: dict) -> dict:
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
|
sg.Button(
|
||||||
|
_t("operations_gui.unlock"), key="--UNLOCK--", size=(45, 1)
|
||||||
|
),
|
||||||
sg.Button(
|
sg.Button(
|
||||||
_t("operations_gui.stats"),
|
_t("operations_gui.stats"),
|
||||||
key="--STATS--",
|
key="--STATS--",
|
||||||
size=(45, 1),
|
size=(45, 1),
|
||||||
)
|
),
|
||||||
],
|
],
|
||||||
[sg.Button(_t("generic.quit"), key="--EXIT--")],
|
[sg.Button(_t("generic.quit"), key="--EXIT--")],
|
||||||
],
|
],
|
||||||
|
@ -259,6 +264,7 @@ def operations_gui(full_config: dict) -> dict:
|
||||||
"--QUICK-CHECK--",
|
"--QUICK-CHECK--",
|
||||||
"--FULL-CHECK--",
|
"--FULL-CHECK--",
|
||||||
"--REPAIR-INDEX--",
|
"--REPAIR-INDEX--",
|
||||||
|
"--REPAIR-PACKS--",
|
||||||
"--REPAIR-SNAPSHOTS--",
|
"--REPAIR-SNAPSHOTS--",
|
||||||
"--UNLOCK--",
|
"--UNLOCK--",
|
||||||
"--FORGET--",
|
"--FORGET--",
|
||||||
|
@ -302,6 +308,16 @@ def operations_gui(full_config: dict) -> dict:
|
||||||
operation = "repair"
|
operation = "repair"
|
||||||
op_args = {"subject": "index"}
|
op_args = {"subject": "index"}
|
||||||
gui_msg = _t("operations_gui.repair_index")
|
gui_msg = _t("operations_gui.repair_index")
|
||||||
|
if event == "--REPAIR-PACKS--":
|
||||||
|
operation = "repair"
|
||||||
|
pack_ids = sg.popup_get_text(
|
||||||
|
_t("operations_gui.repair_packs"), keep_on_top=True
|
||||||
|
)
|
||||||
|
op_args = {
|
||||||
|
"subject": "packs",
|
||||||
|
"pack_ids": pack_ids,
|
||||||
|
}
|
||||||
|
gui_msg = _t("operations_gui.repair_pack")
|
||||||
if event == "--REPAIR-SNAPSHOTS--":
|
if event == "--REPAIR-SNAPSHOTS--":
|
||||||
operation = "repair"
|
operation = "repair"
|
||||||
op_args = {"subject": "snapshots"}
|
op_args = {"subject": "snapshots"}
|
||||||
|
@ -331,6 +347,7 @@ def operations_gui(full_config: dict) -> dict:
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
logger.error(f"Bogus operation: {operation}")
|
logger.error(f"Bogus operation: {operation}")
|
||||||
|
sg.popup_error(f"Bogus operation: {operation}", keep_on_top=True)
|
||||||
|
|
||||||
event = "---STATE-UPDATE---"
|
event = "---STATE-UPDATE---"
|
||||||
if event == "---STATE-UPDATE---":
|
if event == "---STATE-UPDATE---":
|
||||||
|
|
|
@ -1075,17 +1075,19 @@ class ResticRunner:
|
||||||
return self.convert_to_json_output(result, output, msg=msg, **kwargs)
|
return self.convert_to_json_output(result, output, msg=msg, **kwargs)
|
||||||
|
|
||||||
@check_if_init
|
@check_if_init
|
||||||
def repair(self, subject: str) -> Union[bool, str, dict]:
|
def repair(self, subject: str, pack_ids) -> Union[bool, str, dict]:
|
||||||
"""
|
"""
|
||||||
Check current repo status
|
Check current repo status
|
||||||
"""
|
"""
|
||||||
kwargs = locals()
|
kwargs = locals()
|
||||||
kwargs.pop("self")
|
kwargs.pop("self")
|
||||||
|
|
||||||
if subject not in ["index", "snapshots"]:
|
if subject not in ["index", "packs", "snapshots"]:
|
||||||
self.write_logs(f"Bogus repair order given: {subject}", level="error")
|
self.write_logs(f"Bogus repair order given: {subject}", level="error")
|
||||||
return False
|
return False
|
||||||
cmd = f"repair {subject}"
|
cmd = f"repair {subject}"
|
||||||
|
if pack_ids:
|
||||||
|
cmd += f" {pack_ids}"
|
||||||
result, output = self.executor(cmd)
|
result, output = self.executor(cmd)
|
||||||
if result:
|
if result:
|
||||||
msg = f"Repo successfully repaired:\n{output}"
|
msg = f"Repo successfully repaired:\n{output}"
|
||||||
|
|
|
@ -3,6 +3,8 @@ en:
|
||||||
quick_check: Quick repo check
|
quick_check: Quick repo check
|
||||||
full_check: Full repo check
|
full_check: Full repo check
|
||||||
repair_index: Repair repo index
|
repair_index: Repair repo index
|
||||||
|
repair_packs: Repair repo packs
|
||||||
|
pack_ids: Pack IDs
|
||||||
repair_snapshots: Repair repo snapshots
|
repair_snapshots: Repair repo snapshots
|
||||||
unlock: Unlock repo
|
unlock: Unlock repo
|
||||||
forget_using_retention_policy: Forget using retention polic
|
forget_using_retention_policy: Forget using retention polic
|
||||||
|
|
|
@ -3,6 +3,8 @@ fr:
|
||||||
quick_check: Vérification rapide dépot
|
quick_check: Vérification rapide dépot
|
||||||
full_check: Vérification complète dépot
|
full_check: Vérification complète dépot
|
||||||
repair_index: Réparer les index du dépot
|
repair_index: Réparer les index du dépot
|
||||||
|
repair_packs: Réparer les blocs du dépot
|
||||||
|
pack_ids: Identifiants de blocs
|
||||||
repair_snapshots: Réparer les instantanés du dépot
|
repair_snapshots: Réparer les instantanés du dépot
|
||||||
unlock: Déblocage de dépot
|
unlock: Déblocage de dépot
|
||||||
forget_using_retention_policy: Oublier les instantanés en utilisant la stratégie de rétention
|
forget_using_retention_policy: Oublier les instantanés en utilisant la stratégie de rétention
|
||||||
|
|
Loading…
Reference in a new issue