fix(backup): fallback to file backup in dump-only mode when no DB dump is possible
Some checks failed
CI (make tests, stable, publish) / make test (push) Has been cancelled
CI (make tests, stable, publish) / Mark stable + publish image (SemVer tags only) (push) Has been cancelled

- Change DB backup helpers to return whether a dump was actually produced
- Detect DB containers without successful dumps in --dump-only mode
- Fallback to file backups with a warning instead of skipping silently
- Refactor DB dump logic to return boolean status
- Add E2E test covering dump-only fallback when databases.csv entry is missing

https://chatgpt.com/share/6951a659-2b0c-800f-aafa-3e89ae1eb697
This commit is contained in:
Kevin Veen-Birkenbach
2025-12-28 22:51:12 +01:00
parent d563dce20f
commit df32671cec
3 changed files with 225 additions and 30 deletions

View File

@@ -72,28 +72,27 @@ def requires_stop(containers: list[str], images_no_stop_required: list[str]) ->
return True
return False
def backup_mariadb_or_postgres(
*,
container: str,
volume_dir: str,
databases_df: "pandas.DataFrame",
database_containers: list[str],
) -> bool:
) -> tuple[bool, bool]:
"""
Returns True if the container is a DB container we handled.
Returns (is_db_container, dumped_any)
"""
for img in ["mariadb", "postgres"]:
if has_image(container, img):
backup_database(
dumped = backup_database(
container=container,
volume_dir=volume_dir,
db_type=img,
databases_df=databases_df,
database_containers=database_containers,
)
return True
return False
return True, dumped
return False, False
def _backup_dumps_for_volume(
@@ -102,21 +101,26 @@ def _backup_dumps_for_volume(
vol_dir: str,
databases_df: "pandas.DataFrame",
database_containers: list[str],
) -> bool:
) -> tuple[bool, bool]:
"""
Create DB dumps for any mariadb/postgres containers attached to this volume.
Returns True if at least one dump was produced.
Returns (found_db_container, dumped_any)
"""
found_db = False
dumped_any = False
for c in containers:
if backup_mariadb_or_postgres(
is_db, dumped = backup_mariadb_or_postgres(
container=c,
volume_dir=vol_dir,
databases_df=databases_df,
database_containers=database_containers,
):
)
if is_db:
found_db = True
if dumped:
dumped_any = True
return dumped_any
return found_db, dumped_any
def main() -> int:
@@ -137,18 +141,26 @@ def main() -> int:
containers = containers_using_volume(volume_name)
vol_dir = create_volume_directory(version_dir, volume_name)
# Old behavior: DB dumps are additional to file backups.
_backup_dumps_for_volume(
found_db, dumped_any = _backup_dumps_for_volume(
containers=containers,
vol_dir=vol_dir,
databases_df=databases_df,
database_containers=args.database_containers,
)
# dump-only: skip ALL file rsync backups
# dump-only logic:
if args.dump_only:
continue
if found_db and not dumped_any:
print(
f"WARNING: dump-only requested but no DB dump was produced for DB volume '{volume_name}'. Falling back to file backup.",
flush=True,
)
# continue to file backup below
else:
# keep old behavior: skip file backups
continue
# skip file backup if all linked containers are ignored
if volume_is_fully_ignored(containers, args.images_no_backup_required):