{%- from "kopia/map.jinja" import kopia with context -%} #!/usr/bin/env python3 # vim: ft=python import sys import argparse import subprocess from subprocess import Popen, PIPE KOPIA_EXEC="/usr/local/bin/kopia" KOPIA_PASSWORD="{{ params.password|default('') }}" KOPIA_CONFIG_PATH="/etc/kopia/{{ name }}/repo.config" ENV = { "KOPIA_PASSWORD": KOPIA_PASSWORD, "KOPIA_CONFIG_PATH": KOPIA_CONFIG_PATH, } parser = argparse.ArgumentParser(prog='{{ name }} backup') def init(mode="filesystem", path=None, bucket=None, prefix=None, gateway=None, region=None, ak=None, sak=None): if mode == "filesystem" and path: repo_connect = Popen(f"{KOPIA_EXEC} repository connect filesystem --config-file={KOPIA_CONFIG_PATH} --path={path} -p {KOPIA_PASSWORD}", shell=True, stdout=PIPE, stderr=PIPE) repo_create = Popen(f"{KOPIA_EXEC} repository create filesystem --config-file={KOPIA_CONFIG_PATH} --path={path} -p {KOPIA_PASSWORD}" , shell=True, stdout=PIPE, stderr=PIPE) elif mode == "s3" and prefix and gateway and region and ak and sak: cmd_create = f"{KOPIA_EXEC} repository create s3 --config-file={KOPIA_CONFIG_PATH} --bucket={bucket} --prefix={prefix}/ --endpoint={gateway} --region={region} --access-key={ak} --secret-access-key={sak} -p {KOPIA_PASSWORD} --no-check-for-updates --description='{{ name }} repository'" cmd_connect = f"{KOPIA_EXEC} repository connect s3 --config-file={KOPIA_CONFIG_PATH} --bucket={bucket} --prefix={prefix}/ --endpoint={gateway} --region={region} --access-key={ak} --secret-access-key={sak} -p {KOPIA_PASSWORD} --no-check-for-updates --description='{{ name }} repository'" run_create = Popen(cmd_create, shell=True, stdout=PIPE, stderr=PIPE) run_create.wait() if run_create.returncode == 0: print("successfully created repository") run_connect = Popen(cmd_connect, shell=True, stdout=PIPE, stderr=PIPE) run_connect.wait() if run_connect.returncode == 0: print("successfully connected to repository") else: print("no valid mode or missing informations") return None return True def set_policy(compression="zstd"): cmd_policy = f"{KOPIA_EXEC} policy set --global --config-file={KOPIA_CONFIG_PATH} --compression={compression} --keep-latest={{ params.keep_latest|default(7) }} --keep-hourly 0 --keep-daily {{ params.keep_daily|default(7) }} --keep-weekly {{ params.keep_weekly|default(4) }} --keep-monthly {{ params.keep_monthly|default(6) }} --keep-annual 0 --one-file-system=true -p {KOPIA_PASSWORD}" run_policy = Popen(cmd_policy, shell=True, stdout=PIPE, stderr=PIPE) run_policy.wait() if run_policy.returncode == 0: print("successfully set repository policy") return run_policy.returncode == 0 def set_cache(size=500, limit=1000): rcs = [] cmds_cache = [f"{KOPIA_EXEC} cache set --content-cache-size-mb {size} --config-file={KOPIA_CONFIG_PATH} -p {KOPIA_PASSWORD}", f"{KOPIA_EXEC} cache set --content-cache-size-limit-mb {limit} --config-file={KOPIA_CONFIG_PATH} -p {KOPIA_PASSWORD}"] for cmd_cache in cmds_cache: run_cache = Popen(cmd_cache, shell=True, stdout=PIPE, stderr=PIPE) run_cache.wait() rcs.append(run_cache.returncode == 0) if all(rcs): print("successfully set cache policy") return all(rcs) def run(before_tasks=[]): rcs = [] for cmd_task in before_tasks: run_task = Popen(cmd_task, shell=True) run_task.wait() rcs.append(run_task.returncode == 0) if not all(rcs): return False cmd_launch = f"{KOPIA_EXEC} snapshot create {{ params.dirs|map(attribute='path')|join(' ') }} --config-file={KOPIA_CONFIG_PATH} -p {KOPIA_PASSWORD}" run_launch = Popen(cmd_launch, shell=True) run_launch.wait() return run_launch.returncode == 0 def list_snapshots(): cmd_list = f"{KOPIA_EXEC} snapshot list --config-file={KOPIA_CONFIG_PATH} -p {KOPIA_PASSWORD}" run_list = Popen(cmd_list, shell=True) run_list.wait() return run_list.returncode == 0 if __name__ == "__main__": parser.add_argument('action', nargs="?") args = parser.parse_args() res_init = init(mode="s3", bucket="kopia", prefix="{{ name }}", gateway="{{ kopia.repos[params.repo].gateway|default('gateway.storjshare.io') }}", region="{{ kopia.repos[params.repo].region|default('EU1') }}", ak="{{ kopia.repos[params.repo].ak }}", sak="{{ kopia.repos[params.repo].sak }}") if not res_init: print("init error") sys.exit(1) if args.action == "run": if not set_policy(): print("set policy error") sys.exit(1) if not set_cache({{ kopia.repos[params.repo].cache_size|default(500) }},{{ kopia.repos[params.repo].cache_limit|default(1000) }}): print("set cache error") sys.exit(1) if not run(before_tasks={{ params.before_tasks|default([]) }}): print("run error") sys.exit(1) elif args.action == "env": print();print("# source this to use kopia with this repo") for k,v in ENV.items(): print(f"export {k}=\"{v}\"") else: list_snapshots()