gc

package
v3.0.0-alpha.2 Latest Latest
Warning

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

Go to latest
Published: Nov 5, 2026 License: BSD-2-Clause Imports: 9 Imported by: 0

Documentation

Overview

Package gc deletes backup chains by retention rules and cleans up dangling archives. It is the only destructive operation on a backup storage, so every run first builds a plan that can be inspected (tt backup gc --dry-run) and only then executes it.

Index

Constants

View Source
const DefaultOrphanAge = 24 * time.Hour

Variables

This section is empty.

Functions

This section is empty.

Types

type Backup

type Backup struct {
	// BackupID identifies the backup.
	BackupID string `json:"backup_id"`
	// ManifestKey is deleted first: a manifest without archives breaks recovery
	// loudly, archives without a manifest are collected by the next run.
	ManifestKey string `json:"manifest_key"`
	// ArchiveKeys are the archives the manifest referred to, sorted by key.
	ArchiveKeys []string `json:"archive_keys"`
}

Backup is one backup scheduled for deletion.

type Options

type Options struct {
	// KeepFull keeps the last N healthy backup chains; 0 means the rule is unset.
	KeepFull int
	// KeepDays keeps backups created within the last N days; 0 means unset.
	KeepDays int
	// OrphanAge is the minimum age of a dangling archive eligible for deletion.
	OrphanAge time.Duration
	// Now is the reference time for age rules; zero means time.Now().
	Now time.Time
}

Options are the retention rules of one gc run.

type Orphan

type Orphan struct {
	// Key is the storage key of the archive.
	Key string `json:"key"`
	// LastModified is when the storage last wrote the archive.
	LastModified time.Time `json:"last_modified"`
}

Orphan is a dangling archive scheduled for deletion.

type Plan

type Plan struct {
	// Backups are ordered group by group, newest backup of a group first.
	Backups []Backup `json:"backups"`
	// Orphans are dangling archives, sorted by key.
	Orphans []Orphan `json:"orphans"`
	// Notes explain what the run deliberately left alone.
	Notes []string `json:"notes"`
}

Plan is everything one gc run would delete, in deletion order.

func BuildPlan

func BuildPlan(
	ctx context.Context,
	store storage.Storage,
	opts Options,
) (*Plan, error)

BuildPlan works out what a gc run with these options would delete. It only reads the storage.

func (*Plan) Archives

func (p *Plan) Archives() int

Archives counts the archives of every backup in the plan.

func (*Plan) Empty

func (p *Plan) Empty() bool

Empty reports whether the plan deletes nothing.

type Result

type Result struct {
	// Backups is the number of backups whose manifest was deleted.
	Backups int `json:"backups_deleted"`
	// Archives is the number of archives deleted together with their backup.
	Archives int `json:"archives_deleted"`
	// Orphans is the number of dangling archives deleted.
	Orphans int `json:"orphans_deleted"`
	// Kept lists dangling archives that were skipped after a second look.
	Kept []string `json:"orphans_kept"`
}

Result is what a gc run actually deleted. Deleting a key that does not exist is a success on every backend, so the counts can only be as honest as the plan: BuildPlan keeps out of it the keys the storage does not hold, and this is the one number that tells an operator a destructive run did what it said.

func Execute

func Execute(
	ctx context.Context,
	store storage.Storage,
	plan *Plan,
) (*Result, error)

Execute deletes what the plan describes. Backups go first and, inside one backup, the manifest goes before its archives, so that an interrupted run leaves collectable garbage instead of a manifest pointing at nothing: the archives left behind are collected once they are older than --orphan-age.

Jump to

Keyboard shortcuts

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