Fix full restore pipeline, add bind-mount backup, two-tier test suite#19
Merged
Conversation
…st suite Fixes #18 (restore only restored volumes) and addresses #14 (separate volume tars — already implemented, now validated by tests). **Restore improvements (fixes #18)** - restore/restore-images.sh (new): docker load each saved image tar - restore/restore-containers.sh (new): reconstruct docker run from inspect JSON (name, image, env, ports, volumes, restart, network); build_run_cmd() factored out for unit-testability; -f replaces existing - restore/restore-all.sh: wire images → volumes → bind mounts → containers in both interactive and non-interactive (-s) modes - restore/restore-volumes.sh: fix cut -f1 -d. bug that broke dotted volume names; use ${filename%.tar.gz} expansion; add docker volume create before restore; guard missing/empty volumes dir **Bind-mount backup/restore (new -B flag, opt-in)** - backup/backup-bind-mounts.sh: tar -P each bind-mount source path per container; write manifest.json mapping archive → original host path - restore/restore-bind-mounts.sh: restore each archive to its original path via tar -P; respects -f; skips missing archives and existing paths - backup-manager.sh: add -B flag; wire into backup-all.sh and restore-all.sh **Other fixes** - backup/sync-dropbox.sh: rewrite to match current layout (volumes/*.tar.gz + per-container image/data files); old code uploaded stale .tar.xz paths - backup-manager.sh: fix tar_opts default (remove inner single quotes) - backup/backup-all.sh: wire $tar_opts into compress step so -t flag works - Readme.md: fix -b → -p flag error; full rewrite documenting all flags, backup layout, restore order, -B opt-in, jq dependency, testing tiers **Two-tier test suite** Unit tests (bats, no daemon, 38 tests): - test/backup-volumes.bats: confirm #14 — one tar per volume, correct names (incl. dotted), no duplication - test/restore-volumes.bats: regression for the cut parsing bug - test/restore-all.bats: guard #18 — all three restore steps triggered - test/restore-containers.bats: build_run_cmd correctness + skip/force - test/backup-bind-mounts.bats: archive/manifest creation, skip on missing - test/restore-bind-mounts.bats: file restoration, skip/force behaviour - test/helpers/docker: stub recording all calls to $DOCKER_LOG - test/fixtures/: canned inspect JSON Integration tests (real Docker-in-Docker, 13 assertions): - test/integration/run.sh: host orchestrator — starts docker:28-dind, mounts repo read-only, installs deps, runs e2e, always tears down - test/integration/e2e.sh: full cycle — create volume+bind+container, backup -B -s, wipe everything incl. alpine image, restore -B -s -f, assert image/volume data/bind data/container running/env/restart/ports CI (.github/workflows/main.yml): - unit job (macos-13): shellcheck all scripts + bats test/*.bats - integration job (ubuntu-latest): bash test/integration/run.sh
This was referenced Jul 1, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
docker load), volumes, bind-mount host paths (-B), and recreates containers from saved inspect JSON in the correct order.-Bflag — opt-in bind-mount backup/restore: archives each host path per container withtar -P, stores amanifest.json, restores in place. Required for containers like Portainer that store config under host paths (e.g./portainer/Files/AppData).sync-dropbox.shrewritten to match actual backup layout (old code uploaded stale.tar.xzpaths);tar_optswired into compress step;-b→-pflag typo in README fixed.New files
restore/restore-images.shdocker loadeach saved image tarrestore/restore-containers.shdocker runfrom inspect JSON;build_run_cmd()is unit-testablebackup/backup-bind-mounts.shrestore/restore-bind-mounts.shtest/helpers/docker$DOCKER_LOGtest/fixtures/test/*.batstest/integration/run.shdocker:28-dind, runs e2e, tears downtest/integration/e2e.shTest plan
shellcheck *.sh backup/**.sh restore/*.sh test/integration/*.sh -e SC2154 -e SC1091 -e SC2317— cleanbats test/*.bats— 38/38 pass (no daemon)bash test/integration/run.sh— 13/13 assertions pass (real dind cycle: volume data, bind data, image reload, container running, env/restart/ports preserved)