Skip to content

feat(backup): add custom database backup mode#20

Open
AmirKenzo wants to merge 3 commits into
PasarGuard:mainfrom
AmirKenzo:main
Open

feat(backup): add custom database backup mode#20
AmirKenzo wants to merge 3 commits into
PasarGuard:mainfrom
AmirKenzo:main

Conversation

@AmirKenzo

@AmirKenzo AmirKenzo commented Jun 9, 2026

Copy link
Copy Markdown

سلام 👋

یه قابلیت جدید به بخش بکاپ اضافه کردم که به کاربر اجازه میده علاوه بر دیتابیس اصلی پاسارگارد، از دیتابیس‌های دیگه هم بکاپ بگیره.

قبلش فقط دیتابیس دیفالت پاسارگارد رو پوشش می‌داد، ولی الان اگه دیتابیس روی یه کانتینر جدا باشه هم میشه راحت بهش وصل شد و بکاپ گرفت.

پشتیبانی هم کامل برای اینا اضافه شده:

  • MariaDB
  • MySQL
  • PostgreSQL
  • TimescaleDB

هیچ چیزی توی حالت قبلی تغییر نکرده و همون روال دیفالت همچنان مثل قبل کار می‌کنه. این فقط یه حالت اختیاریه برای سناریوهای کاستوم.

Summary by CodeRabbit

  • New Features
    • Added a configurable "Custom Database" backup mode to create SQL dumps from Docker-hosted databases, with interactive setup, view/edit screens, and saved configuration.
    • Added a matching custom restore flow that targets the configured container/database, verifies credentials and container state, and restores the generated dump with retry/failure handling.

@coderabbitai

coderabbitai Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@AmirKenzo, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 33 minutes and 56 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4f9bb47f-2e85-41b1-bd1f-793ffe9bf76a

📥 Commits

Reviewing files that changed from the base of the PR and between 940217a and 2df0b4d.

📒 Files selected for processing (2)
  • lib/pasarguard-backup.sh
  • lib/pasarguard-restore.sh

Walkthrough

This PR adds custom database backup and restore mode functionality. It extends the backup service configuration to prompt for and persist database mode settings, implements database validation and dump helpers, integrates custom backup into the backup execution, and extends restore to conditionally use custom restore flows for MySQL/MariaDB and PostgreSQL based on backup configuration.

Changes

Custom Database Backup and Restore

Layer / File(s) Summary
Backup service configuration UI and environment management
lib/pasarguard-backup.sh
Extends backup_service setup to prompt for database mode via prompt_backup_database_mode, persists BACKUP_CUSTOM_ENABLED, BACKUP_DB_TYPE, and BACKUP_DB_CONTAINER to ENV_FILE, displays mode label in view output, adds menu option in edit to reconfigure mode, and cleans up mode-related vars on service removal.
Database backup helpers for validation and SQL dump
lib/pasarguard-backup.sh
Implements helper functions: mask_database_password, is_backup_custom_enabled, read_backup_env_var, get_backup_database_mode_label, save_backup_database_mode_config, prompt_backup_database_mode, normalize_custom_db_type, custom_db_client_cmd, custom_db_dump_cmd, custom_db_type_label, log_custom_backup_config, validate_custom_backup_container, ensure_custom_backup_container_running, resolve_custom_backup_db_password, resolve_restore_db_password, validate_custom_backup_credentials, validate_custom_backup_database_exists, dump_custom_backup_database, and perform_custom_database_backup to support custom database backup operations (masking function currently returns a placeholder).
Backup command custom mode execution
lib/pasarguard-backup.sh
Modifies backup_command to check is_backup_custom_enabled, log and mask custom database configuration, execute perform_custom_database_backup to produce db_backup.sql, update db_type from BACKUP_DB_TYPE, and continue with default SQLALCHEMY-based flow for non-custom mode.
Restore configuration and custom mode detection
lib/pasarguard-restore.sh
Extends restore_command to declare variables for backup custom settings (current_backup_custom_enabled, current_backup_db_type, current_backup_db_container, custom_restore_mode), load these values from .env, and conditionally enable custom restore mode by validating database type, ensuring custom backup container is running, and validating credentials; falls back to standard SQLALCHEMY_DATABASE_URL requirement if unavailable.
Restore execution branching for custom mode
lib/pasarguard-restore.sh
Updates restore confirmation output to display custom-mode-specific warnings, branches MySQL/MariaDB restore to use ensure_custom_backup_container_running instead of standard container verification and executes custom restore attempt with fallback and cleanup, and branches PostgreSQL/TimescaleDB restore to use custom container handling and resolve missing password via resolve_restore_db_password.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • PasarGuard/scripts#8: Both PRs modify backup_command in lib/pasarguard-backup.sh around database type/container resolution and credential handling (main PR adds a custom DB backup path and env-driven overrides).
  • PasarGuard/scripts#16: Overlaps in Postgres/TimescaleDB restore flow changes and branching logic that this PR also adjusts for custom restore mode.

Poem

🐰 A backup's tale with custom flair,
I hop into containers with care,
Dumping SQL, then I hide,
Restore by mode — I'll be your guide,
Crunching carrots, safe and square. 🥕

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 4.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat(backup): add custom database backup mode' directly and clearly summarizes the main change: adding a new custom database backup mode feature.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@lib/pasarguard-backup.sh`:
- Around line 499-503: The script currently writes the raw user-supplied
BACKUP_DB_CONTAINER value (which can be a transient container ID) into ENV_FILE;
instead resolve that input to a stable container name before persisting. When
backup_custom_enabled is true and before appending BACKUP_DB_CONTAINER to
ENV_FILE, try to resolve the provided value (backup_db_container) with docker
inspect --format '{{.Name}}' or docker ps lookup, strip any leading slash, and
fall back to the original value only if resolution fails; then write the
resolved stable container name (and BACKUP_DB_TYPE as before) into ENV_FILE so
later docker inspect/docker exec calls use a persistent container name.
- Around line 1151-1156: The credential check for PostgreSQL/TimescaleDB
currently attempts to connect to the "postgres" database which rejects valid
roles that can only access the target DB; update the docker exec psql calls in
the postgresql | timescaledb) branch (and the other occurrence around
validate_custom_backup_credentials()) to connect to -d "$db_name" instead of -d
postgres (or otherwise use the provided DB name variable), ensuring the psql
invocations inside validate_custom_backup_credentials() use "$db_name" so roles
limited to the application DB validate correctly.

In `@lib/pasarguard-restore.sh`:
- Around line 450-451: The restore logic currently prefers
current_backup_db_type/current_backup_db_container at runtime but later
overwrites .env with the archive's BACKUP_DB_TYPE/BACKUP_DB_CONTAINER, causing
future backups to target the wrong DB; update the .env write path (the block
that persists BACKUP_DB_CONTAINER, BACKUP_DB_TYPE and related
DB_*/SQLALCHEMY_DATABASE_URL entries between approx. the custom restore and the
final .env rewrite) to write the actual in-use values instead of the archive
values—use current_backup_db_type or custom_db_type_raw and
current_backup_db_container or custom_container (whichever was chosen at
runtime) when persisting BACKUP_DB_TYPE and BACKUP_DB_CONTAINER so the preserved
.env matches the restore target.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 52e950ea-7c87-4a80-a06f-54c91772181e

📥 Commits

Reviewing files that changed from the base of the PR and between 8687ff5 and a565592.

📒 Files selected for processing (2)
  • lib/pasarguard-backup.sh
  • lib/pasarguard-restore.sh

Comment thread lib/pasarguard-backup.sh
Comment thread lib/pasarguard-backup.sh
Comment thread lib/pasarguard-restore.sh
- Resolve container IDs to stable names before persisting
- Validate PostgreSQL credentials against the target database
- Preserve current BACKUP_* configuration after restore

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
lib/pasarguard-backup.sh (2)

1135-1145: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

preferred_password is reading the wrong positional argument.

This helper defines one override password, but preferred_password is assigned from ${3:-} instead of ${2:-}. Any caller passing (db_type, preferred_password) will silently ignore the override and fall back to .env/root credentials.

Suggested fix
 resolve_restore_db_password() {
     local db_type="$1"
-    local preferred_password="${3:-}"
+    local preferred_password="${2:-}"
 
     if [ -n "$preferred_password" ]; then
         printf '%s\n' "$preferred_password"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/pasarguard-backup.sh` around lines 1135 - 1145, In
resolve_restore_db_password the preferred_password is incorrectly read from the
third positional argument (${3:-}) so callers passing (db_type,
preferred_password) are ignored; update the function to take preferred_password
from the second positional parameter (${2:-}) and keep the early-return behavior
(printf + return 0) when a preferred_password is provided, otherwise call
resolve_custom_backup_db_password "$db_type".

1295-1300: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Use the container-start helper in the backup path.

perform_custom_database_backup() still hard-fails on a stopped container by calling validate_custom_backup_container() directly. The file already has ensure_custom_backup_container_running(), so scheduled custom backups will fail after a reboot or manual stop instead of recovering automatically.

Suggested fix
-    if ! validate_custom_backup_container "$container" "$log_file"; then
+    if ! ensure_custom_backup_container_running "$container" "$log_file"; then
         return 1
     fi
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/pasarguard-backup.sh` around lines 1295 - 1300, The backup flow in
perform_custom_database_backup() should ensure the target container is running
instead of hard-failing: call
ensure_custom_backup_container_running("$container" "$log_file") before
validate_custom_backup_container(...) and if that helper returns non-zero,
return 1 (or propagate the failure) so the container is started/recovered
automatically; keep the subsequent validate_custom_backup_credentials(...) call
unchanged. Reference functions: perform_custom_database_backup,
ensure_custom_backup_container_running, validate_custom_backup_container,
validate_custom_backup_credentials.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@lib/pasarguard-backup.sh`:
- Around line 865-870: After resolving the docker name with
resolve_docker_container_name, do not persist an empty BACKUP_DB_CONTAINER; only
call replace_or_append_env_var "BACKUP_DB_CONTAINER" "$container" when container
is non-empty. If the resolution returns empty, skip writing BACKUP_DB_CONTAINER
(and/or remove any existing BACKUP_DB_CONTAINER entry so restore_command won't
read a blank value). Update the logic around enabled/container resolution (the
block using resolve_docker_container_name and replace_or_append_env_var) to
enforce this conditional behavior.

---

Outside diff comments:
In `@lib/pasarguard-backup.sh`:
- Around line 1135-1145: In resolve_restore_db_password the preferred_password
is incorrectly read from the third positional argument (${3:-}) so callers
passing (db_type, preferred_password) are ignored; update the function to take
preferred_password from the second positional parameter (${2:-}) and keep the
early-return behavior (printf + return 0) when a preferred_password is provided,
otherwise call resolve_custom_backup_db_password "$db_type".
- Around line 1295-1300: The backup flow in perform_custom_database_backup()
should ensure the target container is running instead of hard-failing: call
ensure_custom_backup_container_running("$container" "$log_file") before
validate_custom_backup_container(...) and if that helper returns non-zero,
return 1 (or propagate the failure) so the container is started/recovered
automatically; keep the subsequent validate_custom_backup_credentials(...) call
unchanged. Reference functions: perform_custom_database_backup,
ensure_custom_backup_container_running, validate_custom_backup_container,
validate_custom_backup_credentials.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: da434aa3-2187-4067-b915-21c2b0396f8f

📥 Commits

Reviewing files that changed from the base of the PR and between a565592 and 940217a.

📒 Files selected for processing (2)
  • lib/pasarguard-backup.sh
  • lib/pasarguard-restore.sh
🚧 Files skipped from review as they are similar to previous changes (1)
  • lib/pasarguard-restore.sh

Comment thread lib/pasarguard-backup.sh
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant