mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-08 11:46:35 +00:00
fix(backup): preserve numeric ownership and NFS coherence across the DR chain
Every cross-host hop in the backup/recover chain remapped file owners by NAME on the receiving host (rsync -a default; GNU tar extract as root prefers name lookup), so a restored uid-1000-owned 0600 config (n8n) came back owned by a foreign uid and the post-recovery redeploy crash-looped on EACCES. Pass --numeric-ids to the capture, remote-pull, device-sync and restore rsyncs and --numeric-owner to the drill's tar extracts. The drill additionally wiped and rewrote the export subtree directly on the ganesha server's backing filesystem while the server kept running and the nodes kept their client mounts: ganesha's mdcache and the client dentry caches still described the pre-wipe tree, so update-pass tasks were Rejected with readdirent ENOENT for the whole converge window (moodle, espocrm multi-replica). Step 8b now restarts ganesha, remounts every node and probes a real write through the manager's mount, each bounded by timeout so a wedged DinD node fails loudly. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
fdc8fb6d4f
commit
69321d4135
4 files changed
+4
-3
No files matched your search
@@ -49,7 +49,7 @@ def main():
|
||||
|
||||
print("Starting synchronization...")
|
||||
try:
|
||||
rsync_command = ["rsync", "-abP", "--delete", "--delete-excluded"]
|
||||
rsync_command = ["rsync", "-abP", "--numeric-ids", "--delete", "--delete-excluded"]
|
||||
if previous_version_path is not None:
|
||||
rsync_command.append("--link-dest=" + previous_version_path)
|
||||
rsync_command.extend([source_path, current_version_path])
|
||||
|
||||
@@ -45,7 +45,7 @@ trap cleanup_failed_generation ERR
|
||||
|
||||
mkdir -p "${DEST_DIR}"
|
||||
|
||||
rsync_args=(-a --delete)
|
||||
rsync_args=(-a --numeric-ids --delete)
|
||||
if [[ -n "${EXCLUDE_REL}" ]]; then
|
||||
rsync_args+=(--exclude "/${EXCLUDE_REL#/}")
|
||||
fi
|
||||
|
||||
@@ -111,7 +111,7 @@ def pull_backups(hostname: str, backups_dir: str) -> None:
|
||||
Path(local_backup_destination_path).mkdir(parents=True, exist_ok=True)
|
||||
|
||||
rsync_command = (
|
||||
f"rsync -abP --delete --delete-excluded "
|
||||
f"rsync -abP --numeric-ids --delete --delete-excluded "
|
||||
f'--rsync-path="sudo rsync" '
|
||||
f'--link-dest="{local_previous_version_dir}" '
|
||||
f'"{remote_source_path}" "{local_backup_destination_path}"'
|
||||
|
||||
@@ -88,6 +88,7 @@ class DirectoryRecovery(ABC):
|
||||
[
|
||||
"rsync",
|
||||
"-a",
|
||||
"--numeric-ids",
|
||||
"--delete",
|
||||
*self.rsync_extra_args,
|
||||
f"{self.source_dir}/",
|
||||
|
||||
Reference in new issue
Block a user