Files

60 lines
2.3 KiB
PowerShell

param(
[string]$ComposeFile = "compose.yaml",
[string]$DataPath = "./data",
[string]$OutputDirectory = "./backups"
)
$ErrorActionPreference = "Stop"
$timestamp = (Get-Date).ToUniversalTime().ToString("yyyyMMddTHHmmssZ")
$resolvedData = (Resolve-Path -LiteralPath $DataPath).Path
$output = [System.IO.Path]::GetFullPath($OutputDirectory)
New-Item -ItemType Directory -Force -Path $output | Out-Null
$archive = Join-Path $output "memrelay-$timestamp.tar.gz"
$manifest = Join-Path $output "memrelay-$timestamp.json"
$archiveName = [System.IO.Path]::GetFileName($archive)
$images = @(& docker compose -f $ComposeFile config --images)
if ($LASTEXITCODE -ne 0) {
throw "Unable to read Compose image versions."
}
& docker compose -f $ComposeFile exec -T memrelay python -c `
"import os, sqlite3; p=os.path.join(os.environ.get('MEMRELAY_DATA_DIR', '/data/memrelay'), 'db', 'memrelay.sqlite3'); c=sqlite3.connect(p); print(c.execute('PRAGMA wal_checkpoint(TRUNCATE)').fetchone()); c.close()" | Out-Host
if ($LASTEXITCODE -ne 0) {
throw "Unable to checkpoint the MemRelay database."
}
docker compose -f $ComposeFile stop | Out-Host
if ($LASTEXITCODE -ne 0) {
throw "Unable to stop MemRelay services."
}
try {
& docker run --rm --user "1000:1000" `
--mount "type=bind,source=$resolvedData,target=/source,readonly" `
--mount "type=bind,source=$output,target=/backup" `
alpine:3.22 tar -czf "/backup/$archiveName" -C /source .
if ($LASTEXITCODE -ne 0) {
throw "Unable to create the backup archive."
}
$hash = (Get-FileHash -Algorithm SHA256 -LiteralPath $archive).Hash.ToLowerInvariant()
@{
product = "MemRelay"
created_at = (Get-Date).ToUniversalTime().ToString("o")
archive = $archiveName
sha256 = $hash
compose_file = $ComposeFile
images = $images
} | ConvertTo-Json | Set-Content -Encoding UTF8 -LiteralPath $manifest
"$hash $archiveName" | Set-Content -Encoding ASCII -LiteralPath "$archive.sha256"
Write-Host "Backup created: $archive"
}
catch {
Remove-Item -Force -ErrorAction SilentlyContinue -LiteralPath $archive, $manifest, "$archive.sha256"
throw
}
finally {
docker compose -f $ComposeFile start | Out-Host
if ($LASTEXITCODE -ne 0) {
Write-Error "Backup finished, but MemRelay services could not be restarted."
}
}