Skip to content

redis-persistent backup fails on empty /data: shell glob *.rdb matches nothing, backup errors on first run #507

Description

@gchaix

PR #498 changed the redis-persistent backup command to only back up *.rdb files rather than the entire /data directory. The command fails when /data contains no .rdb files.

The uselagoon/redis-7-persistent image sets WORKDIR /data, so the *.rdb glob expands correctly from /data when files are present. However, busybox ash does not support nullglob, so when no .rdb files exist (a fresh Redis pod that has not yet written dump.rdb), the shell passes the literal string *.rdb to tar. Tar then tries to open a file named *.rdb inside /data via the -C path and fails.

This means the first k8up backup of a newly-provisioned Redis persistent service will always fail. After Redis writes its first dump.rdb, subsequent backups succeed.

Reproduction

# Fails: empty /data, no .rdb files
docker run --rm uselagoon/redis-7-persistent \
  /bin/sh -c "tar -cf - -C /data --exclude='temp-*.rdb' *.rdb"
# tar: *.rdb: Cannot stat: No such file or directory

# Works once dump.rdb exists
docker run --rm uselagoon/redis-7-persistent \
  /bin/sh -c "touch /data/dump.rdb && tar -cf - -C /data --exclude='temp-*.rdb' *.rdb" | tar -t
# dump.rdb

Fix

The simplest approach that stays closest to the original command:

/bin/sh -c "ls /data/*.rdb 2>/dev/null | grep -q . && timeout 5400 tar -cf - -C /data --exclude='temp-*.rdb' *.rdb || tar -cf - --files-from=/dev/null"

Or using find to handle the empty-directory case gracefully:

/bin/sh -c "timeout 5400 find /data -maxdepth 1 -name '*.rdb' ! -name 'temp-*.rdb' -print0 | tar -cf - --null -T -"

The previous command (tar ... .) did not have this issue since . always matches the directory itself, even when empty.

Notes

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions