Files
SocialPub/PrivaPub/Infrastructure/Backup/ArchiveManifest.cs
T

65 lines
2.5 KiB
C#
Raw Normal View History

using System.Text.Json;
using System.Text.Json.Serialization;
namespace PrivaPub.Infrastructure.Backup
{
// What a backup holds (manifest.json at its root): enough to check it is whole, to restore it on this host only, and to
// rebuild what Mongo had (each collection's indexes).
public sealed class ArchiveManifest
{
public const int CurrentFormat = 1;
public const string FileName = "manifest.json";
public int Format { get; set; } = CurrentFormat;
public string Kind { get; set; }//nightly, manual, pre-deploy, pre-restore, uploaded
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
public string Host { get; set; }//BackendBaseAddress: URIs and media URLs are stored whole, so only this host can restore it
public string AppCommit { get; set; }
public string AppRef { get; set; }
public string NewestMigration { get; set; }
public int MigrationNumber { get; set; }
public bool Consistent { get; set; }//read at one instant (a snapshot session on a replica set)
public bool DbOnly { get; set; }//no media files, only their list (the deploy's, which can't link www-data's files)
public List<CollectionEntry> Collections { get; set; } = [];
public List<ExcludedEntry> Excluded { get; set; } = [];
public MediaEntry Media { get; set; } = new();
public sealed class CollectionEntry
{
public string Name { get; set; }
public long Count { get; set; }
public long Bytes { get; set; }
public string Sha256 { get; set; }
public List<string> Indexes { get; set; } = [];//each as canonical Extended JSON
}
public sealed class ExcludedEntry
{
public string Name { get; set; }
public string Why { get; set; }
}
public sealed class MediaEntry
{
public int Files { get; set; }
public long Bytes { get; set; }
public int Missing { get; set; }
public List<string> List { get; set; } = [];
}
static readonly JsonSerializerOptions Json = new() { WriteIndented = true, PropertyNamingPolicy = JsonNamingPolicy.CamelCase, DefaultIgnoreCondition = JsonIgnoreCondition.Never };
public static ArchiveManifest Read(string directory)
{
var path = Path.Combine(directory, FileName);
return File.Exists(path) ? JsonSerializer.Deserialize<ArchiveManifest>(File.ReadAllText(path), Json) : default;
}
public void Write(string directory)
{
using var file = new FileStream(Path.Combine(directory, FileName), FileMode.Create, FileAccess.Write);
JsonSerializer.Serialize(file, this, Json);
file.Flush(flushToDisk: true);
}
}
}