A restore on the live pasture: its own scenario, and two fixes it found

tools/pasture/scenarios/restore.sh backs the pasture up from the administrator's endpoint, then alice_restore deletes a
post and makes another, mastouser follows her, she blocks bob_restore and carol_restore is made; the restore, asked for
from the endpoint, keeps every protective act (19 checks). town.sh renew <peer> signs a peer's town accounts in again,
since a restore ends every session.

It found that a backup listed media files already missing when it was made, so verifying it failed and the restore was
refused: a manifest now lists only the files it holds (refusals are cut to five lines). And a local post made after the
backup now comes back as a deleted row, as a deletion leaves it, so it answers 410 and its id is never given again;
DeletedObject holds remote tombstones only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LsXgEaXee4GCU1hwYgPJXw
This commit is contained in:
thepraandClaude Opus 5.5 committed 2026-10-07 12:24:23 +02:00
1 parent 9ad96f560d
commit bdc8be4508
8 files changed
+133 -26

No files matched your search

+13 -12
View File
@@ -111,20 +111,21 @@ namespace PrivaPub.Infrastructure.Backup
}
manifest.Consistent = replica;
manifest.Media.List = [.. media];
if (!dbOnly)
foreach (var relative in media)
// the files it holds (or, db-only, lists); a row whose file was already gone is only counted
foreach (var relative in media)
{
var source = new[] { context.MediaRoot, context.TrashRoot }.Select(root => Inside(root, relative)).FirstOrDefault(File.Exists);
if (source == default)
{
var source = new[] { context.MediaRoot, context.TrashRoot }.Select(root => Inside(root, relative)).FirstOrDefault(File.Exists);
if (source == default)
{
manifest.Media.Missing++;
continue;
}
HardLink.LinkOrCopy(source, Inside(Path.Combine(partial, "media"), relative));
manifest.Media.Files++;
manifest.Media.Bytes += new FileInfo(source).Length;
manifest.Media.Missing++;
continue;
}
if (!dbOnly)
HardLink.LinkOrCopy(source, Inside(Path.Combine(partial, "media"), relative));
manifest.Media.List.Add(relative);
manifest.Media.Files++;
manifest.Media.Bytes += new FileInfo(source).Length;
}
manifest.Write(partial);
Directory.Move(partial, Path.Combine(context.BackupsRoot, id));