storagecheck

package
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Oct 19, 2026 License: Apache-2.0 Imports: 18 Imported by: 0

Documentation

Overview

Package storagecheck states which database schemas a build can operate on and verifies a supplied SQLite file against that policy before a daemon serves requests or restores work. The check never migrates or repairs a database: an incompatible file is refused with the action its operator has to take. Upgrade applies the packaged migrations only when an operator runs it explicitly. BootstrapFresh creates only new, private databases from those same packaged migrations.

Index

Constants

View Source
const (
	// Schema 31 stores owner-managed executor presentation labels.
	// Schema 29 records authenticated schedule history; schema 30 / executor 9
	// add durable aggregate egress grants.
	MinimumDispatcherVersion int64 = 31
	MinimumExecutorVersion   int64 = 9
)

Minimum supported schema versions. Every version from the minimum up to the version the packaged migrations produce is served without a migration step. Raise the minimum together with a migration the daemon's queries depend on: an older database can then no longer answer them and must be refused instead of failing later during service.

Variables

View Source
var (
	ErrAbsent     = errors.New("database not found")
	ErrUnknown    = errors.New("unknown database")
	ErrUnreadable = errors.New("unreadable database")
	ErrOutdated   = errors.New("outdated database schema")
	ErrNewer      = errors.New("newer database schema")
	ErrIncomplete = errors.New("incomplete database schema")
	// ErrDataLoss accompanies ErrOutdated when the upgrade of the database
	// drops the runs and logs it recorded.
	ErrDataLoss = errors.New("upgrade drops recorded data")
)

Reasons a database is refused. An absent database, a readable one that is not ours, and a storage fault are separate answers for an operator.

Functions

func BootstrapFresh added in v0.3.0

func BootstrapFresh(ctx context.Context, role Role, path string) error

BootstrapFresh applies the canonical migrations to a new, private database. The caller must own the mode-0700 parent and keep it exclusively under its control until this function returns. Existing databases are never upgraded.

func Check

func Check(ctx context.Context, role Role, path string) error

Check verifies the database at path against the schema policy of the role. It opens the file read-only and leaves its bytes unchanged even when it refuses it, so a refused database can still be inspected or restored. A database in WAL mode can still gain the usual -wal and -shm companions.

func CheckForService added in v0.3.0

func CheckForService(ctx context.Context, role Role, path string) error

CheckForService verifies a database before launching its daemon. A hot rollback journal is recovered only in a temporary copy; the database and journal are left unchanged. The daemon must still call OpenForService to recover the original. This is not an offline-backup or stopped-writer check.

func CheckOpen added in v0.3.0

func CheckOpen(ctx context.Context, role Role, db *sql.DB, path string) error

CheckOpen validates an already-open connection, for maintenance that must recheck the schema while holding exclusive database ownership.

func OpenExclusive added in v0.3.0

func OpenExclusive(ctx context.Context, path string) (*sql.DB, error)

OpenExclusive takes SQLite ownership for offline maintenance. With one connection in EXCLUSIVE locking mode, COMMIT retains the database lock until Close; goose can still use its normal per-migration transactions. This also applies to WAL databases and does not rely on every writer using a sidecar lock. It cannot establish that an idle daemon has stopped; operators must still stop the service before upgrading it. The caller must check the schema and prove shutdown separately, and keep this connection open until its complete maintenance operation has finished.

func OpenForService added in v0.3.0

func OpenForService(ctx context.Context, role Role, path string) (*sql.DB, error)

OpenForService checks an existing database and opens it for the daemon. Unlike Check, it may recover a hot rollback journal left by an interrupted writer. Recovery is first checked on a private copy, so an unknown or unsupported database is still refused without changing the original. It never creates or upgrades the original database. As with the daemon's normal startup, the caller must be the only service using this state.

func Upgrade

func Upgrade(ctx context.Context, role Role, path string, opts ...UpgradeOption) (int64, error)

Upgrade applies the packaged migrations of the role to the database at path and returns the schema version it then records, once Check accepts it. It first refuses, with Check's answers, a path that is absent, unreadable, not this role's Debuglet database, or newer than this build, and writes nothing to it. A database whose upgrade drops the recorded runs is refused the same way with ErrDataLoss unless the caller passes AcceptDataLoss. It takes no backup and expects the daemon using the file to be stopped. It holds an exclusive SQLite connection across every migration and the final check, so another writer cannot interleave between migration commits. Each migration commits on its own; a failed one leaves the earlier ones applied and a later Upgrade continues from the recorded version. The deployment procedure keeps the original backup and leaves the service stopped after a failed upgrade.

Types

type ForeignKeyViolation

type ForeignKeyViolation struct {
	Table  string
	Parent string
	Rows   int
}

ForeignKeyViolation counts the rows of Table that reference a missing row of Parent.

func ForeignKeyViolations

func ForeignKeyViolations(ctx context.Context, path string) ([]ForeignKeyViolation, error)

ForeignKeyViolations reports the rows of the database at path whose references PRAGMA foreign_key_check finds broken. The daemons enforce foreign keys only on new writes, so rows written before they did stay as they are; this is how an operator learns of them. It opens the database read-only and changes nothing.

func (ForeignKeyViolation) String

func (v ForeignKeyViolation) String() string

type Policy

type Policy struct {
	Role Role
	// Minimum is the oldest schema version the daemon serves.
	Minimum int64
	// Current is the version the packaged migrations produce. A database
	// beyond it was written by a newer Debuglet.
	Current int64
	// DropsBelow is the version below which an upgrade drops the recorded
	// runs and their logs (tables debuglets and debuglet_logs): the packaged
	// migration that reaches it recreates both tables empty.
	DropsBelow int64
	// Identity lists tables, with columns, that only this role's database
	// has and that it has carried since its first migration. They are
	// checked before the version, so a path pointing at the other role's
	// database is reported as the wrong file rather than as a wrong version.
	Identity map[string][]string
	// Tables lists the tables the supported schema must contain, with the
	// columns that distinguish a completely applied schema from one whose
	// migrations stopped halfway.
	Tables map[string][]string
}

Policy is the schema contract of one database for this build.

func PolicyFor

func PolicyFor(role Role) (Policy, error)

PolicyFor returns the schema policy of the given role.

func (Policy) Check

func (p Policy) Check(ctx context.Context, path string) error

Check verifies one database against this policy.

func (Policy) CheckDB added in v0.3.0

func (p Policy) CheckDB(ctx context.Context, db *sql.DB) error

CheckDB verifies an already-open database against this policy. The caller owns the handle and its read-only or offline snapshot semantics.

func (Policy) Supports

func (p Policy) Supports(version int64) bool

Supports reports whether a schema version is inside the supported range.

type Role

type Role string

Role names a dispatcher or executor database.

const (
	Dispatcher Role = "dispatcher"
	Executor   Role = "executor"
)

type UpgradeOption added in v0.3.0

type UpgradeOption func(*upgradeOptions)

UpgradeOption changes what Upgrade agrees to do.

func AcceptDataLoss added in v0.3.0

func AcceptDataLoss() UpgradeOption

AcceptDataLoss lets Upgrade apply a migration that drops the recorded runs and their logs. Without it such a database is refused and left unchanged.

Jump to

Keyboard shortcuts

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