make pruning optional / a separate function and also fix log interleaving

This commit is contained in:
dave 2023-09-29 13:55:03 -07:00
parent 5e5e921e57
commit 915278f45d
3 changed files with 45 additions and 12 deletions

View File

@ -4,4 +4,4 @@ CFG_DIR = os.environ.get("RESTICBACKUP_CONFIG_DIR", "/etc/resticbackup.d")
RESTIC_BIN = os.environ.get("RESTICBACKUP_RESTIC_BIN_PATH", "restic")
__version__ = "0.0.6"
__version__ = "0.0.7"

View File

@ -5,7 +5,7 @@ import traceback
import time
from resticbackup import __version__
from resticbackup.types import ClientConfig, load_config, load_base_config, list_configs
from resticbackup.lib import ExecWrapper, init_ok, die, pdie, checkp, runp, get_retention_args, \
from resticbackup.lib import fprint, ExecWrapper, init_ok, die, pdie, checkp, runp, get_retention_args, \
get_newest_snapshot, update_statefile
@ -13,10 +13,13 @@ def cmd_backup(args, parser):
config = load_config(args.name)
try:
run_backup(args.name, config)
# run the backup
backoff(run_backup, args.name, config)
# run retention
if backoff(run_retention, args.name, config):
# TODO don't run prune automatically as it is repo-wide and every other client runs it too. Unnecessary
backoff(run_prune, config)
# run prune (optional)
if args.prune:
backoff(run_prune, config)
# update statefile if configured
if config.statefile:
path = config.statefile.format(name=args.name)
@ -77,7 +80,7 @@ def backoff(func, *args, **kwargs):
traceback.print_exc()
delay = backoff[backoffs]
backoffs += 1
print("...caught, and will be retried in {}m".format(delay))
fprint("...caught, and will be retried in {}m".format(delay))
time.sleep(delay * 60)
@ -121,7 +124,7 @@ def cmd_restore(args, parser):
if not snapshot:
if args.no_snapshots_ok:
print("no snapshots found, but exiting OK")
fprint("no snapshots found, but exiting OK")
return
else:
return die("no snapshots found")
@ -165,15 +168,31 @@ def cmd_list(args, parser):
return pdie(config.run(cmd))
for entry in list_configs():
print(entry)
fprint(entry)
def cmd_exec(args, parser):
checkp(load_config(args.name).run(args.args))
def cmd_prune(args, parser):
if args.name is None:
names = list_configs()
else:
names = [args.name]
configs = [load_config(n) for n in names]
# we only need to prune each repo once, so use a dict to group configs by repo address
configs = {c.repo: c for c in configs}
for config in configs.values():
fprint("pruning:", config.repo)
run_prune(config)
def cmd_version(args, parser):
print(__version__)
fprint(__version__)
def main():
@ -188,6 +207,7 @@ def main():
p_backup = sp_action.add_parser("backup", help="take a backup")
p_backup.set_defaults(func=cmd_backup)
p_backup.add_argument("name", help="name of backup to execute")
p_backup.add_argument('--prune', action='store_true', help='run the prune operation after backup')
# p_backup.add_argument("-c", "--print", action="store_true", help="just print the restic commands instead") # TODO
# p_backup.add_argument("-e", "--env", action="store_true", help="just print the environment variables instead") # TODO
@ -213,6 +233,10 @@ def main():
p_retrieve.add_argument("name", help="backup name")
p_retrieve.add_argument("outdir", help="file path to write to")
p_prune = sp_action.add_parser("prune", help="run the prune function")
p_prune.add_argument("name", nargs="?", help="name of backup to run prune in repo for. Omit for all repos")
p_prune.set_defaults(func=cmd_prune)
p_version = sp_action.add_parser("version", help="display program version")
p_version.set_defaults(func=cmd_version)

View File

@ -5,8 +5,17 @@ import time
import subprocess
def fprint(*args, **kwargs):
"""
print + flush output streams. Helps keep logs correctly interleaved when piping to a file
"""
print(*args, **kwargs)
sys.stdout.flush()
sys.stderr.flush()
def die(msg, rc=1):
print(msg)
fprint(msg)
sys.exit(rc)
@ -36,12 +45,12 @@ class ExecWrapper(object):
def __enter__(self):
for command in self.pre:
print("+", command)
fprint("+", command)
subprocess.check_call(command, shell=True)
def __exit__(self, exc_type, exc_value, exc_tb):
for command in self.post:
print("+", command)
fprint("+", command)
subprocess.check_call(command, shell=True)