Skip to content

v1.1.0

Choose a tag to compare

@shellharbor shellharbor released this 28 Sep 07:01
· 8 commits to main since this release

v1.1.0

Bug-fix release. Four defects were found in review, each capable of producing a backup that looked successful while silently missing data, or a notification that silently failed to retry. All four are fixed with new regression tests, including two run against a real Docker daemon — one of them was verified to actually catch the regression by reverting the fix and confirming the test fails.

Fixed

A backup could silently report success while missing data

  • A source file Backfort could not read (permission denied, an I/O error) used to disappear quietly from the archive while the run was still logged as backup-succeeded. tar --create no longer runs with --ignore-failed-read; GNU tar's own exit status now tells a real read failure (fails the job) apart from the tolerated race of a file changing mid-read (still a warning-only success). Applies to file-source jobs and to Compose named-volume/bind-mount snapshots alike.
  • The archive sanitizer was silently dropping any file or directory whose name merely started with a space — a false positive, since every archive member is transform-prefixed with the literal string data, which never itself starts with whitespace. That check is removed. A name that genuinely can't be represented (a literal newline, carriage return, tab, or invalid UTF-8) is still excluded, but doing so now fails the job with a clear message=unsupported-entries-removed log line instead of quietly publishing an incomplete backup.

command_timeout_seconds now actually stops the process, not just the client

  • Killing the host-side docker/docker compose client — all a timeout wrapper alone can do — does not stop a process it started inside the container's own PID namespace. A hung pg_dump, a restore import, or the volume-snapshot tar kept running, orphaned, long after Backfort had given up and moved on. The actual command is now also wrapped with an in-container timeout, so it's reliably reaped. Requires a timeout binary in the database service and volume-helper images (present in common Debian- and Alpine-based images).

Telegram's plain-text retry could never fire

  • curl --fail discarded the response body on Telegram's own HTTP error status for a rejected HTML message (e.g. a malformed tag in a custom template), so the {"ok":false,...} payload the retry logic needed to inspect never reached it — the designed fallback silently never triggered. notification_curl_post now reads the HTTP status explicitly via --write-out instead of leaning on curl --fail.

Testing

  • New: tests/unreadable-file.sh (unreadable and unsupported source names) and tests/compose-exec-timeout-real.sh (real Docker; proves the in-container process is actually gone, not just detached from a killed client).
  • tests/notify.sh's Telegram-retry scenario now serves a genuine HTTP 400 and exercises the real production code path instead of a canned response.
  • tests/archive-resilience.sh and tests/fidelity.sh updated for the new fail-instead-of-silently-warn behavior.
  • Full suite: 24/24 passing, including fidelity.sh under root with acl/attr.