mirror of
https://github.com/iamxvbaba/gramsrv.git
synced 2026-11-07 15:06:06 +03:00
1a19f0d984
Operators had no supported way to move a deployment or to recover one. This
adds cmd/gramsrv-backup, which captures the PostgreSQL databases, the media and
key tree, Redis and the configuration into a single verifiable bundle, and
restores it on another host.
backup / restore / verify, with MANIFEST.json recording the source commit, the
schema version and exact row counts, and SHA256SUMS in sha256sum(1) format.
Components are captured independently (server, grammystore) since each has its
own database and usually its own container; pg_dump and redis-cli can come from
the host or from docker exec.
Portability is the point of the dump format:
- plain SQL rather than the custom format, so any psql can replay it and the
client need not match the server
- --clean --if-exists so a bundle can be replayed over a populated database
- --no-owner --no-privileges, and no --create, so the target role and database
name are not baked into the artifact
- restored with ON_ERROR_STOP=1 and --single-transaction, so a failure cannot
leave a half-applied schema
- \restrict, \unrestrict and SET transaction_timeout are stripped on the way
in; they are PostgreSQL 17 specific and break older clients and servers
- the target major version is checked before the restore starts
Freezing (--freeze-units, --freeze-containers) is optional because pg_dump is
already MVCC-consistent; it exists so the media tree is byte consistent, and
everything stopped is restarted from a defer even when the capture fails.
Verification re-hashes every artifact, decompresses it, walks tar members, and
cross-checks file_blobs against the media tree, reporting missing and corrupt
objects. check-media.sh runs the live form of that check.
Also included: shell and PowerShell wrappers, a migration runbook in
docs/backup-restore.md, and internal/doclint, which fails the build when tracked
markdown leaks a key, a token or a credential so documentation stays safe to
publish.
72 lines
2.2 KiB
PowerShell
72 lines
2.2 KiB
PowerShell
#!/usr/bin/env pwsh
|
|
# Capture a gramsrv backup bundle with sensible defaults for a monolith
|
|
# deployment. Every unrecognised argument is forwarded to gramsrv-backup.
|
|
#
|
|
# ./scripts/backup.ps1 -Out D:\gramsrv-backup\20261004 -Component all
|
|
#
|
|
# The tool reads .env for database credentials, so nothing secret is passed on
|
|
# the command line.
|
|
[CmdletBinding()]
|
|
param(
|
|
[Parameter(ValueFromRemainingArguments = $true)]
|
|
[string[]]$ToolArgs
|
|
)
|
|
|
|
$ErrorActionPreference = 'Stop'
|
|
|
|
$RepoRoot = Split-Path -Parent $PSScriptRoot
|
|
$Binary = Join-Path $RepoRoot 'bin/gramsrv-backup.exe'
|
|
|
|
function Test-HasFlag([string]$Name, [string[]]$Items) {
|
|
foreach ($item in $Items) {
|
|
if ($item -eq $Name -or $item.StartsWith("$Name=")) { return $true }
|
|
}
|
|
return $false
|
|
}
|
|
|
|
function Build-Binary {
|
|
if (-not (Get-Command go -ErrorAction SilentlyContinue)) {
|
|
throw "go is required to build $Binary"
|
|
}
|
|
Write-Host "building $Binary"
|
|
# Serial compilation keeps peak memory low enough for small hosts.
|
|
Push-Location $RepoRoot
|
|
try {
|
|
$env:GOFLAGS = '-p=1'
|
|
go build -o $Binary ./cmd/gramsrv-backup
|
|
if ($LASTEXITCODE -ne 0) { throw "go build failed" }
|
|
} finally {
|
|
Pop-Location
|
|
}
|
|
}
|
|
|
|
if ($ToolArgs -contains '--help') {
|
|
Get-Content -Raw (Join-Path $PSScriptRoot 'backup.sh') | Select-String -Pattern '(?s)usage\(\).*?^}' | ForEach-Object { $_.Matches.Value }
|
|
exit 0
|
|
}
|
|
|
|
if (-not (Test-Path $Binary)) { Build-Binary }
|
|
|
|
$forwarded = @()
|
|
if (-not (Test-HasFlag '--out' $ToolArgs)) {
|
|
$stamp = (Get-Date).ToUniversalTime().ToString('yyyyMMdd')
|
|
$forwarded += @('--out', (Join-Path (Split-Path -Parent $RepoRoot) "gramsrv-backup-$stamp"))
|
|
}
|
|
if (-not (Test-HasFlag '--repo-dir' $ToolArgs)) {
|
|
$forwarded += @('--repo-dir', $RepoRoot)
|
|
}
|
|
if (-not (Test-HasFlag '--pg-tools' $ToolArgs) -and (Get-Command docker -ErrorAction SilentlyContinue)) {
|
|
$forwarded += @('--pg-tools', 'docker')
|
|
}
|
|
if (-not (Test-HasFlag '--redis-tools' $ToolArgs) -and (Get-Command docker -ErrorAction SilentlyContinue)) {
|
|
$forwarded += @('--redis-tools', 'docker')
|
|
}
|
|
|
|
Push-Location $RepoRoot
|
|
try {
|
|
& $Binary backup @forwarded @ToolArgs
|
|
exit $LASTEXITCODE
|
|
} finally {
|
|
Pop-Location
|
|
}
|