diff --git a/backup/__init__.py b/backup/__init__.py new file mode 100644 index 0000000..b668da9 --- /dev/null +++ b/backup/__init__.py @@ -0,0 +1 @@ +from .main import main \ No newline at end of file diff --git a/backup/main.py b/backup/main.py new file mode 100755 index 0000000..b35ae63 --- /dev/null +++ b/backup/main.py @@ -0,0 +1,65 @@ +#!/usr/bin/env python3 + +from pathlib import Path +from typing import Iterable, Set + +import click +import docker +import restic +from docker.models.containers import Container + +client = docker.from_env() + +def stop_containers(names: Iterable[str]) -> Set[Container]: + names = set(names) + stopped_containers = set() + for con in client.containers.list(): + if con.name in names: + stopped_containers.add(con) + try: + con.stop() + except: + print('Error') + break + else: + print(f'Stopped [{con.short_id}] {con.name}') + return stopped_containers + + +def start_containers(containers: Iterable[Container]): + for con in containers: + try: + con.start() + except: + print(f'Error starting: [{con.short_id}] {con.name}') + else: + print(f'Started: [{con.short_id}] {con.name}') + + +@click.command() +@click.argument('src', type=click.Path(exists=True, file_okay=False, readable=True, resolve_path=True, path_type=Path)) +@click.option('-ds', '--docker-stop', type=click.STRING, + help='Comma-delimited list of the container names to stop before running the backup') +def main(src: Path, docker_stop: str = None): + print(type(src).__name__, src) + + if docker_stop is not None: + cons = stop_containers(docker_stop.split(',')) + else: + cons = set() + + pw_file = Path('/run/secrets/restic-pw').resolve() + restic.password_file = pw_file.as_posix() + + restic.backup( + paths=[''], + dry_run=True + ) + + print(f'{len(restic.snapshots())} snapshots found in the repo') + + start_containers(cons) + + +if __name__ == '__main__': + main() diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..ebf5def --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,13 @@ +[build-system] +requires = ["setuptools", "wheel"] +build-backend = "setuptools.build_meta" + +[project] +name = "file-backups" +version = "0.1.0" +description = "With restic and Docker" +license = {file="LICENSE"} +requires-python = ">=3.10" + +[project.scripts] +backup = "backup:main" diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..284102a --- /dev/null +++ b/requirements.txt @@ -0,0 +1,6 @@ +docker +resticpy +click +rich + +ipython \ No newline at end of file