Compare commits

...

2 Commits

Author SHA1 Message Date
a18b9ed6d0 backup: track errors/warnings from borg; add prefix to them
This also ignores the "file changed while we backed it up" error, because
that isn't important enough to warrant sending an email.
2021-10-17 00:16:43 -04:00
756dbe1898 backup: fix mypy-detected errors 2021-10-17 00:14:14 -04:00

View File

@ -251,11 +251,12 @@ def main(argv: list[str]):
args = parser.parse_args()
config = Config(args.config)
backup = Backup(config, args.dry_run)
# Parse variables from vars.sh
hostname = os.uname().nodename
borg = str(base / "borg.sh")
notify = str(base / "notify.sh")
borg_sh = str(base / "borg.sh")
notify_sh = str(base / "notify.sh")
try:
with open(args.vars) as f:
for line in f:
@ -267,14 +268,13 @@ def main(argv: list[str]):
if var == "HOSTNAME":
hostname = value
if var == "BORG":
borg = value
borg_sh = value
if var == "BORG_DIR":
notify = pathlib.Path(value) / "notify.sh"
notify_sh = str(pathlib.Path(value) / "notify.sh")
except Exception as e:
self.log('W', f"failed to parse variables from {args.vars}: {str(e)}")
backup.log('W', f"failed to parse variables from {args.vars}: {str(e)}")
# Run backup
backup = Backup(config, args.dry_run)
captured_output: list[bytes] = []
if args.dry_run:
@ -285,7 +285,7 @@ def main(argv: list[str]):
backup.run(out)
sys.stdout.flush()
else:
borg = subprocess.Popen([borg,
borg = subprocess.Popen([borg_sh,
"create",
"--verbose",
"--progress",
@ -304,6 +304,9 @@ def main(argv: list[str]):
if borg.stdin is None:
raise Exception("no pipe")
borg_saw_warnings = 0
borg_saw_errors = 0
# Use a thread to capture output
def reader_thread(fh):
last_progress = 0
@ -313,7 +316,20 @@ def main(argv: list[str]):
if ((data['type'] == 'log_message' or
data['type'] == 'progress_message')
and 'message' in data):
line = (data['message'] + '\n').encode()
# Count warnings and errors, but ignore some.
changed_msg = "file changed while we backed it up"
if data['levelname'] == 'WARNING':
prefix = "warning: "
if changed_msg not in data['message']:
borg_saw_warnings += 1
elif data['levelname'] not in ('DEBUG', 'INFO'):
prefix = "error: "
borg_saw_errors += 1
else:
prefix = ""
line = (prefix + data['message'] + '\n').encode()
elif data['type'] == 'archive_progress':
now = time.time()
if now - last_progress > 10:
@ -359,8 +375,12 @@ def main(argv: list[str]):
ret = borg.returncode
if ret < 0:
backup.log('E', f"borg exited with signal {-ret}")
elif ret != 0:
backup.log('E', f"borg exited with return code {ret}")
elif ret == 2 or borg_saw_errors:
backup.log('E', f"borg exited with errors (ret={ret})")
elif ret == 1 or borg_saw_warnings:
backup.log('W', f"borg exited with warnings (ret={ret})")
else:
backup.log('E', f"borg exited with unknown error code {ret}")
# See if we had any errors
warnings = sum(1 for (letter, msg) in backup.logs if letter == 'W')
@ -405,12 +425,12 @@ def main(argv: list[str]):
if errmsg and warnmsg:
summary = f"{errmsg}, {warnmsg}"
elif errors:
summary = errmsg
summary = errmsg or ""
else:
summary = warnmsg
summary = warnmsg or ""
# Call notify.sh
res = subprocess.run([notify, summary, email], input=body_text)
res = subprocess.run([notify_sh, summary, email], input=body_text)
if res.returncode != 0:
backup.log('E', f"failed to send notification")
errors += 1