backup: capture borg output for later reporting

This commit is contained in:
Jim Paris 2021-10-15 23:26:51 -04:00 committed by Jim Paris
parent 0c74f1676c
commit 59ad2b5b4d

View File

@ -10,7 +10,9 @@ import re
import sys
import stat
import time
import select
import pathlib
import threading
import subprocess
import typing
@ -245,13 +247,17 @@ def main(argv: list[str]):
args = parser.parse_args()
config = Config(args.config)
# Run backup
backup = Backup(config, args.dry_run)
captured_output: list[bytes] = []
if args.dry_run:
if args.debug:
backup.run(sys.stdout.buffer)
else:
with open(os.devnull, "wb") as out:
backup.run(out)
sys.stdout.flush()
else:
borg = subprocess.Popen([args.borg,
"create",
@ -264,12 +270,33 @@ def main(argv: list[str]):
"--paths-from-stdin",
"--paths-delimiter", "\\0",
"::'{hostname}-{now:%Y%m%d-%H%M%S}'"],
stdin=subprocess.PIPE)
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
if borg.stdin is None:
raise Exception("no pipe")
# Use a thread to capture output
def reader_thread(fh):
os.set_blocking(fh.fileno(), False)
while True:
ready = select.select([fh.fileno()], [], [])
if not len(ready[0]):
break
data = fh.read(8192)
if not len(data):
break
sys.stdout.buffer.write(data)
sys.stdout.flush()
captured_output.append(data)
fh.close()
reader = threading.Thread(target=reader_thread, args=(borg.stdout,))
reader.daemon = True
reader.start()
try:
# Give borg some time to start, just to clean up stdout
time.sleep(2)
time.sleep(1)
backup.run(borg.stdin)
except BrokenPipeError:
sys.stderr.write(f"broken pipe\n")
@ -279,13 +306,12 @@ def main(argv: list[str]):
except BrokenPipeError:
pass
borg.wait()
reader.join()
ret = borg.returncode
if ret < 0:
sys.stderr.write(f"error: process exited with signal {-ret}\n")
return 1
backup.log('E', f"borg exited with signal {-ret}")
elif ret != 0:
sys.stderr.write(f"error: process exited with return code {ret}\n")
return ret
backup.log('E', f"borg exited with return code {ret}")
return 0