mirror of
https://github.com/kevinveenbirkenbach/docker-volume-backup.git
synced 2026-07-17 14:15:13 +00:00
fix(backup,restore): make restore drills replayable and leave swarm tasks alone
Restore fixes, both hit by the infinito svc-bkp e2e drill: - mariadb --empty dropped tables one docker exec at a time with SET FOREIGN_KEY_CHECKS=0 issued in a separate client session, so the session-scoped toggle never applied and any FK-referenced parent table (mailu.users) died with ERROR 1451. Issue the toggle and all DROPs in one session. - postgres --empty now drops only current_user-owned objects (extension members like pg_trgm's set_limit are superuser-owned) with IF EXISTS absorbing CASCADE fallout, and the replay skips superuser-only dump lines (COMMENT ON EXTENSION, ALTER DEFAULT PRIVILEGES) that abort an app-user psql run under ON_ERROR_STOP. Backup fixes: - pg_dump now runs with --no-owner --no-privileges so future dumps are replayable by the owning app user in the first place. - Swarm task containers are never stopped or started manually: the orchestrator replaces a stopped task and a later docker start fails on the detached overlay network. filter_stoppable skips them visibly and the whitelist stop check ignores them. Validated end to end against a live infinito compose stack: the full svc-bkp-volume-2-local drill (verify, restore cycle, sql replay for mailu, keycloak and one more db) passes with these patches applied. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -16,8 +16,10 @@ from .docker import (
|
||||
change_containers_status,
|
||||
containers_using_volume,
|
||||
docker_volume_names,
|
||||
filter_stoppable,
|
||||
get_image_info,
|
||||
has_image,
|
||||
is_swarm_task,
|
||||
)
|
||||
from .shell import execute_shell_command
|
||||
from .volume import backup_volume
|
||||
@@ -66,9 +68,13 @@ def volume_is_fully_ignored(
|
||||
|
||||
def requires_stop(containers: list[str], images_no_stop_required: list[str]) -> bool:
|
||||
"""
|
||||
Stop is required if ANY container image is NOT in the whitelist patterns.
|
||||
Stop is required if ANY stoppable container image is NOT in the
|
||||
whitelist patterns. Swarm task containers never count: baudolo must
|
||||
not cycle them (see docker.is_swarm_task).
|
||||
"""
|
||||
for c in containers:
|
||||
if is_swarm_task(c):
|
||||
continue
|
||||
img = get_image_info(c)
|
||||
if not any(pat in img for pat in images_no_stop_required):
|
||||
return True
|
||||
@@ -219,20 +225,22 @@ def main() -> int:
|
||||
|
||||
if args.everything:
|
||||
# "everything": always do pre-rsync, then stop + rsync again
|
||||
stoppable = filter_stoppable(containers)
|
||||
backup_volume(versions_dir, volume_name, vol_dir)
|
||||
change_containers_status(containers, "stop")
|
||||
change_containers_status(stoppable, "stop")
|
||||
backup_volume(versions_dir, volume_name, vol_dir)
|
||||
if not args.shutdown:
|
||||
change_containers_status(containers, "start")
|
||||
change_containers_status(stoppable, "start")
|
||||
continue
|
||||
|
||||
# default: rsync, and if needed stop + rsync
|
||||
backup_volume(versions_dir, volume_name, vol_dir)
|
||||
if requires_stop(containers, args.images_no_stop_required):
|
||||
change_containers_status(containers, "stop")
|
||||
stoppable = filter_stoppable(containers)
|
||||
change_containers_status(stoppable, "stop")
|
||||
backup_volume(versions_dir, volume_name, vol_dir)
|
||||
if not args.shutdown:
|
||||
change_containers_status(containers, "start")
|
||||
change_containers_status(stoppable, "start")
|
||||
|
||||
# Stamp the backup version directory using dirval (python lib)
|
||||
stamp_directory(version_dir)
|
||||
|
||||
Reference in New Issue
Block a user