53 lines
2.0 KiB
PowerShell
53 lines
2.0 KiB
PowerShell
param(
|
|
[Parameter(Mandatory = $true)][string]$Archive,
|
|
[string]$ComposeFile = "compose.yaml",
|
|
[string]$DataPath = "./data",
|
|
[switch]$Force
|
|
)
|
|
|
|
$ErrorActionPreference = "Stop"
|
|
$resolvedArchive = (Resolve-Path -LiteralPath $Archive).Path
|
|
$target = [System.IO.Path]::GetFullPath($DataPath)
|
|
$targetRoot = [System.IO.Path]::GetPathRoot($target).TrimEnd('\', '/')
|
|
if ($target.TrimEnd('\', '/') -eq $targetRoot) {
|
|
throw "Refusing to restore into a filesystem root."
|
|
}
|
|
$checksumFile = "$resolvedArchive.sha256"
|
|
if (Test-Path -LiteralPath $checksumFile) {
|
|
$expected = ((Get-Content -LiteralPath $checksumFile -TotalCount 1) -split '\s+')[0]
|
|
$actual = (Get-FileHash -Algorithm SHA256 -LiteralPath $resolvedArchive).Hash.ToLowerInvariant()
|
|
if ($actual -ne $expected.ToLowerInvariant()) {
|
|
throw "Backup checksum verification failed."
|
|
}
|
|
}
|
|
New-Item -ItemType Directory -Force -Path $target | Out-Null
|
|
if ((Get-ChildItem -Force -LiteralPath $target | Select-Object -First 1) -and -not $Force) {
|
|
throw "Target data directory is not empty. Re-run with -Force after verifying the archive."
|
|
}
|
|
|
|
docker compose -f $ComposeFile stop | Out-Host
|
|
if ($LASTEXITCODE -ne 0) {
|
|
throw "Unable to stop MemRelay services."
|
|
}
|
|
try {
|
|
if ($Force) {
|
|
Get-ChildItem -Force -LiteralPath $target | Remove-Item -Recurse -Force
|
|
}
|
|
$archiveDirectory = [System.IO.Path]::GetDirectoryName($resolvedArchive)
|
|
$archiveName = [System.IO.Path]::GetFileName($resolvedArchive)
|
|
& docker run --rm --user "1000:1000" `
|
|
--mount "type=bind,source=$archiveDirectory,target=/backup,readonly" `
|
|
--mount "type=bind,source=$target,target=/target" `
|
|
alpine:3.22 tar -xzf "/backup/$archiveName" -C /target
|
|
if ($LASTEXITCODE -ne 0) {
|
|
throw "Unable to extract the backup archive."
|
|
}
|
|
Write-Host "Restore completed: $target"
|
|
}
|
|
finally {
|
|
docker compose -f $ComposeFile up -d | Out-Host
|
|
if ($LASTEXITCODE -ne 0) {
|
|
Write-Error "Restore finished, but MemRelay services could not be started."
|
|
}
|
|
}
|