diff --git a/src/restic_compose_backup/backup_runner.py b/src/restic_compose_backup/backup_runner.py index 8474f9f..41f127c 100644 --- a/src/restic_compose_backup/backup_runner.py +++ b/src/restic_compose_backup/backup_runner.py @@ -3,6 +3,7 @@ import os import docker from restic_compose_backup.config import Config +from restic_compose_backup import utils logger = logging.getLogger(__name__) @@ -11,7 +12,7 @@ def run(image: str = None, command: str = None, volumes: dict = None, environment: dict = None, labels: dict = None, source_container_id: str = None): logger.info("Starting backup container") config = Config() - client = docker.DockerClient(base_url=config.docker_base_url) + client = utils.docker_client() container = client.containers.run( image, diff --git a/src/restic_compose_backup/cli.py b/src/restic_compose_backup/cli.py index db6e9b6..b4b7e22 100644 --- a/src/restic_compose_backup/cli.py +++ b/src/restic_compose_backup/cli.py @@ -9,6 +9,7 @@ from restic_compose_backup import ( ) from restic_compose_backup.config import Config from restic_compose_backup.containers import RunningContainers +from restic_compose_backup import utils logger = logging.getLogger(__name__) @@ -54,6 +55,9 @@ def status(config, containers): logger.info("Backup currently running?: %s", containers.backup_process_running) logger.info("%s Detected Config %s", "-" * 25, "-" * 25) + if containers.stale_backup_process_containers: + utils.remove_containers(containers.stale_backup_process_containers) + logger.info("Initializing repository (may fail if already initalized)") restic.init_repo(config.repository) diff --git a/src/restic_compose_backup/containers.py b/src/restic_compose_backup/containers.py index b29cbed..9eabb90 100644 --- a/src/restic_compose_backup/containers.py +++ b/src/restic_compose_backup/containers.py @@ -66,6 +66,9 @@ class Container: """All configured env vars for the container as a list""" return self.get_config('Env') + def remove(self): + self._data.remove() + def get_config_env(self, name) -> str: """Get a config environment variable by name""" # convert to dict and fetch env var by name diff --git a/src/restic_compose_backup/utils.py b/src/restic_compose_backup/utils.py index aef8d99..b03c71d 100644 --- a/src/restic_compose_backup/utils.py +++ b/src/restic_compose_backup/utils.py @@ -1,26 +1,45 @@ import os +import logging +from typing import List from contextlib import contextmanager import docker - from restic_compose_backup.config import Config +logger = logging.getLogger(__name__) + TRUE_VALUES = ['1', 'true', 'True', True, 1] -def list_containers(): +def docker_client(): + config = Config() + return docker.DockerClient(base_url=config.docker_base_url) + + +def list_containers() -> List[dict]: """ List all containers. Returns: List of raw container json data from the api """ - config = Config() - client = docker.DockerClient(base_url=config.docker_base_url) + client = docker_client() all_containers = client.containers.list(all=True) client.close() return [c.attrs for c in all_containers] +def remove_containers(containers: List['Container']): + client = docker_client() + logger.info('Attempting to delete stale backup process containers') + for container in containers: + logger.info(' -> deleting %s', container.name) + try: + c = client.containers.get(container.name) + c.remove() + except Exception as ex: + logger.exception(ex) + + def is_true(value): """ Evaluates the truthfullness of a bool value in container labels