backup

package
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 27, 2026 License: MIT Imports: 18 Imported by: 0

Documentation

Overview

Package backup creates PostgreSQL dumps with pg_dump and stores them in S3 on a daily/monthly/yearly rotation. It deduplicates unchanged dumps by SHA-256, prunes daily backups past a retention window, and can be driven either on a schedule or on demand through an authenticated HTTP endpoint.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func HumanizeSize

func HumanizeSize(b int) string

HumanizeSize formats a byte count using binary units (KB/MB/GB/...), or plain bytes below 1 KB. For example HumanizeSize(1572864) returns "1.50 MB".

func PgDump

func PgDump(ctx context.Context, db DatabaseConfig) ([]byte, error)

PgDump produces a SQL dump of the given database by invoking the pg_dump binary. It is the default Dumper used by New. On AWS Lambda the binary ships in a layer mounted at /opt/opt/bin; elsewhere it is resolved from PATH.

Types

type Config

type Config struct {
	S3            S3API          // S3 client (required)
	Bucket        string         // destination bucket (required)
	Database      DatabaseConfig // database to dump (required)
	RetentionDays int            // daily backups to keep; <= 0 means 7
	Dump          Dumper         // dump implementation; nil means PgDump
}

Config configures a Handler.

type DatabaseConfig

type DatabaseConfig struct {
	Host     string
	Port     string
	User     string
	Password string
	Database string
}

DatabaseConfig holds the connection parameters used to invoke pg_dump.

func ParseDatabaseURL

func ParseDatabaseURL(dbURL string) (DatabaseConfig, error)

ParseDatabaseURL parses a PostgreSQL connection string (for example "postgresql://user:pass@host:5432/dbname") into a DatabaseConfig. The port defaults to 5432 and the database name defaults to "postgres" when absent.

type Dumper

type Dumper func(ctx context.Context, db DatabaseConfig) ([]byte, error)

Dumper produces a SQL dump of the given database. The default implementation is PgDump; tests inject their own.

type EventHandler

type EventHandler struct {
	// contains filtered or unexported fields
}

EventHandler adapts a Handler to AWS Lambda invocations: EventBridge schedules (and direct invokes) run a deduplicated backup, while API Gateway v2 HTTP requests to /run run an authenticated, forced backup.

func NewEventHandler

func NewEventHandler(h *Handler, apiKey string) *EventHandler

NewEventHandler wraps h, authenticating HTTP requests against apiKey.

func (*EventHandler) Dispatch

func (e *EventHandler) Dispatch(ctx context.Context, raw json.RawMessage) (any, error)

Dispatch routes a raw Lambda event to the HTTP handler when it is an API Gateway v2 request, or to a scheduled (deduplicated) backup otherwise.

type Handler

type Handler struct {
	// contains filtered or unexported fields
}

Handler runs backups against a bucket and database.

func New

func New(cfg Config) *Handler

New builds a Handler from cfg, applying defaults for RetentionDays (7) and Dump (PgDump).

func (*Handler) Run

func (h *Handler) Run(ctx context.Context, force bool) (*Result, error)

Run produces a dump and stores it. A normal run stores the daily backup only when the dump differs from the most recent daily backup. When force is true (a manual invocation) it stores today's backup even if it matches an older one, but still skips rewriting today's file when that file is already identical. Monthly and yearly backups are created when missing, and daily backups older than the retention window are pruned.

type Result

type Result struct {
	Status     string `json:"status"`      // always "ok" on success
	Action     string `json:"action"`      // "created" or "skipped"
	Reason     string `json:"reason"`      // why the daily backup was created/skipped
	Key        string `json:"key"`         // today's daily backup S3 key
	Size       string `json:"size"`        // human-readable dump size (e.g. "12.34 MB")
	SizeBytes  int    `json:"size_bytes"`  // size of the dump in bytes
	DurationMs int64  `json:"duration_ms"` // wall-clock time of the run
}

Result summarizes a single backup run.

type S3API

type S3API interface {
	HeadObject(ctx context.Context, params *s3.HeadObjectInput, optFns ...func(*s3.Options)) (*s3.HeadObjectOutput, error)
	GetObject(ctx context.Context, params *s3.GetObjectInput, optFns ...func(*s3.Options)) (*s3.GetObjectOutput, error)
	PutObject(ctx context.Context, params *s3.PutObjectInput, optFns ...func(*s3.Options)) (*s3.PutObjectOutput, error)
	ListObjectsV2(ctx context.Context, params *s3.ListObjectsV2Input, optFns ...func(*s3.Options)) (*s3.ListObjectsV2Output, error)
	DeleteObject(ctx context.Context, params *s3.DeleteObjectInput, optFns ...func(*s3.Options)) (*s3.DeleteObjectOutput, error)
}

S3API is the subset of the AWS S3 client used by Handler. It is satisfied by *s3.Client and allows the storage layer to be mocked in tests.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL