mirror of
https://github.com/netinvent/npbackup.git
synced 2025-11-11 14:42:37 +08:00
Refactor pre/post exec hooks
This commit is contained in:
parent
2c70dabf1b
commit
a2582bebf7
1 changed files with 99 additions and 77 deletions
|
|
@ -1090,6 +1090,9 @@ class NPBackupRunner:
|
||||||
"""
|
"""
|
||||||
Run backup after checking if no recent backup exists, unless force == True
|
Run backup after checking if no recent backup exists, unless force == True
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
start_time = datetime.now(timezone.utc)
|
||||||
|
|
||||||
stdin_from_command = self.repo_config.g("backup_opts.stdin_from_command")
|
stdin_from_command = self.repo_config.g("backup_opts.stdin_from_command")
|
||||||
if not stdin_filename:
|
if not stdin_filename:
|
||||||
stdin_filename = self.repo_config.g("backup_opts.stdin_filename")
|
stdin_filename = self.repo_config.g("backup_opts.stdin_filename")
|
||||||
|
|
@ -1228,67 +1231,105 @@ class NPBackupRunner:
|
||||||
else:
|
else:
|
||||||
raise ValueError("Unknown source type given")
|
raise ValueError("Unknown source type given")
|
||||||
|
|
||||||
pre_exec_commands_success = True
|
def _exec_commands(
|
||||||
if pre_exec_commands:
|
exec_type: str,
|
||||||
for pre_exec_command in pre_exec_commands:
|
command_list: List[str],
|
||||||
exit_code, output = command_runner(
|
per_command_timeout: int,
|
||||||
pre_exec_command, shell=True, timeout=pre_exec_per_command_timeout
|
failure_is_fatal: bool,
|
||||||
)
|
|
||||||
if exit_code != 0:
|
|
||||||
msg = f"Pre-execution of command {pre_exec_command} failed with:\n{output}"
|
|
||||||
self.write_logs(msg, level="error")
|
|
||||||
if pre_exec_failure_is_fatal:
|
|
||||||
return self.convert_to_json_output(False, msg)
|
|
||||||
else:
|
|
||||||
self.write_logs(msg, level="warning")
|
|
||||||
pre_exec_commands_success = False
|
|
||||||
else:
|
|
||||||
self.write_logs(
|
|
||||||
f"Pre-execution of command {pre_exec_command} succeeded with:\n{output}",
|
|
||||||
level="info",
|
|
||||||
)
|
|
||||||
|
|
||||||
# Run actual backup here
|
|
||||||
if source_type in (
|
|
||||||
None,
|
|
||||||
"folder_list",
|
|
||||||
"files_from_verbatim",
|
|
||||||
"files_from_raw",
|
|
||||||
):
|
):
|
||||||
result = self.restic_runner.backup(
|
commands_success = True
|
||||||
paths=paths,
|
if command_list:
|
||||||
source_type=source_type,
|
for command in command_list:
|
||||||
exclude_patterns=exclude_patterns,
|
exit_code, output = command_runner(
|
||||||
exclude_files=exclude_files,
|
command, shell=True, timeout=per_command_timeout
|
||||||
excludes_case_ignore=excludes_case_ignore,
|
)
|
||||||
exclude_caches=exclude_caches,
|
if exit_code != 0:
|
||||||
exclude_files_larger_than=exclude_files_larger_than,
|
msg = f"{exec_type}-execution of command {command} failed with:\n{output}"
|
||||||
one_file_system=one_file_system,
|
commands_success = False
|
||||||
use_fs_snapshot=use_fs_snapshot,
|
if not failure_is_fatal:
|
||||||
tags=tags,
|
self.write_logs(msg, level="warning")
|
||||||
additional_backup_only_parameters=additional_backup_only_parameters,
|
else:
|
||||||
)
|
self.write_logs(msg, level="error")
|
||||||
elif source_type == "stdin_from_command" and stdin_from_command:
|
self.write_logs(
|
||||||
result = self.restic_runner.backup(
|
"Stopping further execution due to fatal error",
|
||||||
stdin_from_command=stdin_from_command,
|
level="error",
|
||||||
stdin_filename=stdin_filename,
|
)
|
||||||
tags=tags,
|
break
|
||||||
additional_backup_only_parameters=additional_backup_only_parameters,
|
else:
|
||||||
)
|
self.write_logs(
|
||||||
elif read_from_stdin:
|
f"{exec_type}-execution of command {command} succeeded with:\n{output}",
|
||||||
result = self.restic_runner.backup(
|
level="info",
|
||||||
read_from_stdin=read_from_stdin,
|
)
|
||||||
stdin_filename=stdin_filename,
|
return commands_success
|
||||||
tags=tags,
|
|
||||||
additional_backup_only_parameters=additional_backup_only_parameters,
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
raise ValueError("Bogus backup source type given")
|
|
||||||
|
|
||||||
self.write_logs(
|
pre_exec_commands_success = _exec_commands(
|
||||||
f"Restic output:\n{self.restic_runner.backup_result_content}", level="debug"
|
"Pre",
|
||||||
|
pre_exec_commands,
|
||||||
|
pre_exec_per_command_timeout,
|
||||||
|
pre_exec_failure_is_fatal,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if pre_exec_failure_is_fatal and not pre_exec_commands_success:
|
||||||
|
# This logic is more readable than it's negation, let's just keep it
|
||||||
|
result = False
|
||||||
|
else:
|
||||||
|
# Run actual backup here
|
||||||
|
if source_type in (
|
||||||
|
None,
|
||||||
|
"folder_list",
|
||||||
|
"files_from_verbatim",
|
||||||
|
"files_from_raw",
|
||||||
|
):
|
||||||
|
result = self.restic_runner.backup(
|
||||||
|
paths=paths,
|
||||||
|
source_type=source_type,
|
||||||
|
exclude_patterns=exclude_patterns,
|
||||||
|
exclude_files=exclude_files,
|
||||||
|
excludes_case_ignore=excludes_case_ignore,
|
||||||
|
exclude_caches=exclude_caches,
|
||||||
|
exclude_files_larger_than=exclude_files_larger_than,
|
||||||
|
one_file_system=one_file_system,
|
||||||
|
use_fs_snapshot=use_fs_snapshot,
|
||||||
|
tags=tags,
|
||||||
|
additional_backup_only_parameters=additional_backup_only_parameters,
|
||||||
|
)
|
||||||
|
elif source_type == "stdin_from_command" and stdin_from_command:
|
||||||
|
result = self.restic_runner.backup(
|
||||||
|
stdin_from_command=stdin_from_command,
|
||||||
|
stdin_filename=stdin_filename,
|
||||||
|
tags=tags,
|
||||||
|
additional_backup_only_parameters=additional_backup_only_parameters,
|
||||||
|
)
|
||||||
|
elif read_from_stdin:
|
||||||
|
result = self.restic_runner.backup(
|
||||||
|
read_from_stdin=read_from_stdin,
|
||||||
|
stdin_filename=stdin_filename,
|
||||||
|
tags=tags,
|
||||||
|
additional_backup_only_parameters=additional_backup_only_parameters,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
raise ValueError("Bogus backup source type given")
|
||||||
|
|
||||||
|
self.write_logs(
|
||||||
|
f"Restic output:\n{self.restic_runner.backup_result_content}",
|
||||||
|
level="debug",
|
||||||
|
)
|
||||||
|
|
||||||
|
post_exec_commands_success = _exec_commands(
|
||||||
|
"Post",
|
||||||
|
post_exec_commands,
|
||||||
|
post_exec_per_command_timeout,
|
||||||
|
post_exec_failure_is_fatal,
|
||||||
|
)
|
||||||
|
|
||||||
|
# So we must duplicate @exec_time code here since we must call @metrics manually
|
||||||
|
# because it will need restic output from backup function
|
||||||
|
self.exec_time = (datetime.now(timezone.utc) - start_time).total_seconds()
|
||||||
|
try:
|
||||||
|
os.environ["NPBACKUP_EXEC_TIME"] = str(self.exec_time)
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
|
||||||
# Extract backup size from result_string
|
# Extract backup size from result_string
|
||||||
# Metrics will not be in json format, since we need to diag cloud issues until
|
# Metrics will not be in json format, since we need to diag cloud issues until
|
||||||
# there is a fix for https://github.com/restic/restic/issues/4155
|
# there is a fix for https://github.com/restic/restic/issues/4155
|
||||||
|
|
@ -1304,26 +1345,6 @@ class NPBackupRunner:
|
||||||
"Backup is smaller than configured minmium backup size", level="error"
|
"Backup is smaller than configured minmium backup size", level="error"
|
||||||
)
|
)
|
||||||
|
|
||||||
post_exec_commands_success = True
|
|
||||||
if post_exec_commands:
|
|
||||||
for post_exec_command in post_exec_commands:
|
|
||||||
exit_code, output = command_runner(
|
|
||||||
post_exec_command, shell=True, timeout=post_exec_per_command_timeout
|
|
||||||
)
|
|
||||||
if exit_code != 0:
|
|
||||||
msg = f"Post-execution of command {post_exec_command} failed with:\n{output}"
|
|
||||||
self.write_logs(msg, level="error")
|
|
||||||
post_exec_commands_success = False
|
|
||||||
if post_exec_failure_is_fatal:
|
|
||||||
return self.convert_to_json_output(False, msg)
|
|
||||||
else:
|
|
||||||
self.write_logs(msg, level="warning")
|
|
||||||
else:
|
|
||||||
self.write_logs(
|
|
||||||
f"Post-execution of command {post_exec_command} succeeded with:\n{output}",
|
|
||||||
level="info",
|
|
||||||
)
|
|
||||||
|
|
||||||
operation_result = (
|
operation_result = (
|
||||||
result
|
result
|
||||||
and pre_exec_commands_success
|
and pre_exec_commands_success
|
||||||
|
|
@ -1336,6 +1357,7 @@ class NPBackupRunner:
|
||||||
level="info" if operation_result else "error",
|
level="info" if operation_result else "error",
|
||||||
ignore_additional_json=True,
|
ignore_additional_json=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
if not operation_result:
|
if not operation_result:
|
||||||
# patch result if json
|
# patch result if json
|
||||||
if isinstance(result, dict):
|
if isinstance(result, dict):
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue