60 lines
2.3 KiB
PowerShell
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."
|
|
}
|
|
}
|