From 296c67c3f9540b4af747f0a520438cc731e72519 Mon Sep 17 00:00:00 2001 From: mrwogu Date: Tue, 27 May 2025 00:53:35 +0200 Subject: [PATCH] Add support for custom backup provider patterns --- README.md | 15 +++++++++++++ db-auto-backup.py | 33 +++++++++++++++++++++++++++ tests/tests.py | 57 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 105 insertions(+) diff --git a/README.md b/README.md index 302fe84..f11da94 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,18 @@ A script to automatically back up all databases running under docker on a host, - [pgautoupgrade](https://github.com/pgautoupgrade/docker-pgautoupgrade)) - Redis +### Custom Backup Providers + +You can extend the existing backup providers with additional container patterns by setting environment variables: + +``` +CUSTOM_BACKUP_PROVIDER_POSTGRES_PATTERNS=immich-app/postgres,my-custom-postgres +CUSTOM_BACKUP_PROVIDER_MYSQL_PATTERNS=my-custom-mysql,another-mysql-container +CUSTOM_BACKUP_PROVIDER_REDIS_PATTERNS=my-custom-redis +``` + +Each variable should contain a comma-separated list of container patterns to match. + ## Installation This container requires access to the docker socket. This can be done either by mounting `/var/lib/docker.sock`, or using a HTTP proxy to provide it through `$DOCKER_HOST`. @@ -55,6 +67,9 @@ services: environment: - SUCCESS_HOOK_URL=https://hc-ping.com/1234 - INCLUDE_LOGS=true + # Custom backup provider patterns + - CUSTOM_BACKUP_PROVIDER_POSTGRES_PATTERNS=immich-app/postgres,custom-postgres + - CUSTOM_BACKUP_PROVIDER_MYSQL_PATTERNS=my-custom-mysql ``` ### Oneshot diff --git a/db-auto-backup.py b/db-auto-backup.py index 68200d9..0a86d07 100755 --- a/db-auto-backup.py +++ b/db-auto-backup.py @@ -155,6 +155,39 @@ def backup_redis(container: Container) -> str: ), ] +# Extend backup providers with custom patterns from environment variables +# Format: CUSTOM_BACKUP_PROVIDER__PATTERNS=pattern1,pattern2,... +for env_var, value in os.environ.items(): + if env_var.startswith("CUSTOM_BACKUP_PROVIDER_") and env_var.endswith("_PATTERNS"): + provider_name = ( + env_var.replace("CUSTOM_BACKUP_PROVIDER_", "") + .replace("_PATTERNS", "") + .lower() + ) + custom_patterns = [ + pattern.strip() for pattern in value.split(",") if pattern.strip() + ] + + # Find the provider and extend its patterns + for provider in BACKUP_PROVIDERS: + if provider.name.lower() == provider_name: + # Create a new BackupProvider with extended patterns + index = BACKUP_PROVIDERS.index(provider) + BACKUP_PROVIDERS[index] = BackupProvider( + name=provider.name, + patterns=provider.patterns + custom_patterns, + backup_method=provider.backup_method, + file_extension=provider.file_extension, + ) + print( + f"Extended {provider.name} backup provider with patterns: {', '.join(custom_patterns)}" + ) + break + else: + print( + f"Warning: Custom backup provider {provider_name} not found, skipping patterns: {', '.join(custom_patterns)}" + ) + BACKUP_DIR = Path(os.environ.get("BACKUP_DIR", "/var/backups")) SCHEDULE = os.environ.get("SCHEDULE", "0 0 * * *") diff --git a/tests/tests.py b/tests/tests.py index f59ed6e..733f543 100644 --- a/tests/tests.py +++ b/tests/tests.py @@ -130,3 +130,60 @@ def test_get_backup_provider(container_name: str, name: str) -> None: assert provider is not None assert provider.name == name + + +def test_custom_backup_provider_patterns(monkeypatch: Any) -> None: + # Save original backup providers + original_providers = db_auto_backup.BACKUP_PROVIDERS.copy() + + try: + # Set custom patterns environment variable + monkeypatch.setenv( + "CUSTOM_BACKUP_PROVIDER_POSTGRES_PATTERNS", + "immich-app/postgres,custom-postgres", + ) + + # Create a copy of the original providers + test_providers = original_providers.copy() + db_auto_backup.BACKUP_PROVIDERS = test_providers + + # Run the code that processes environment variables + for env_var, value in { + "CUSTOM_BACKUP_PROVIDER_POSTGRES_PATTERNS": "immich-app/postgres,custom-postgres" + }.items(): + if env_var.startswith("CUSTOM_BACKUP_PROVIDER_") and env_var.endswith( + "_PATTERNS" + ): + provider_name = ( + env_var.replace("CUSTOM_BACKUP_PROVIDER_", "") + .replace("_PATTERNS", "") + .lower() + ) + custom_patterns = [ + pattern.strip() for pattern in value.split(",") if pattern.strip() + ] + + for provider in db_auto_backup.BACKUP_PROVIDERS: + if provider.name.lower() == provider_name: + index = db_auto_backup.BACKUP_PROVIDERS.index(provider) + db_auto_backup.BACKUP_PROVIDERS[ + index + ] = db_auto_backup.BackupProvider( + name=provider.name, + patterns=provider.patterns + custom_patterns, + backup_method=provider.backup_method, + file_extension=provider.file_extension, + ) + break + + # Test with the new custom pattern + provider = db_auto_backup.get_backup_provider(["immich-app/postgres"]) + assert provider is not None + assert provider.name == "postgres" + + provider = db_auto_backup.get_backup_provider(["custom-postgres"]) + assert provider is not None + assert provider.name == "postgres" + finally: + # Restore original backup providers + db_auto_backup.BACKUP_PROVIDERS = original_providers