migrations

package
v0.0.0-...-74321ee Latest Latest
Warning

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

Go to latest
Published: Aug 7, 2026 License: Apache-2.0 Imports: 16 Imported by: 0

Documentation

Overview

Package migrations embeds the SQL migration files for the kagent database schema and provides the runner that applies them at startup.

Index

Constants

This section is empty.

Variables

Functions

func RunUp

func RunUp(ctx context.Context, url string, sources []Source) error

RunUp applies all pending migrations for each source, in slice order.

All PreChecks run first, before any source is applied, so a failed precheck aborts the run before touching the database. Each source is then applied with the same per-track safety behavior: it tolerates a database ahead of this binary (compatibility mode), refuses a dirty-and-ahead database, and rolls itself back if its own Up fails. If a later source fails, previously-applied sources are rolled back to their pre-run versions in reverse order.

ctx is honored at source boundaries and during schema setup and prechecks. golang-migrate's apply is not context-aware, so an in-flight migration is not cancellable.

func VerifyMigrated

func VerifyMigrated(ctx context.Context, url string, sources []Source) error

VerifyMigrated checks, without applying or reverting anything, that every source's migrations have been applied to the database. It is the boot-time guard for the SKIP_MIGRATIONS deployment mode, where migrations run out-of-band (a pipeline or pre-upgrade hook) and the server must refuse to serve a wrong-shaped schema. It issues only SELECTs — never golang-migrate, which creates the tracking table on open — so it is safe on a connection whose role has no DDL privileges.

Per source: a missing tracking table or a version behind this binary's embedded max is an error; a dirty tracking table is an error; a database ahead of the binary is tolerated (compatibility mode), matching RunUp.

func WithMigrator

func WithMigrator(ctx context.Context, url string, src Source, fn func(*migrate.Migrate) error) error

WithMigrator opens a migrator for src against url, runs fn against it, and closes it. The migrator carries the same schema handling, tracking-table configuration, and advisory-lock identity as the orchestrator's own runs, so out-of-band tooling (the `kagent db migrate` CLI) built on this serializes correctly against a concurrently booting server and cannot drift from the startup path. fn's migration operations (Up/Down/Steps/Migrate/Force) each take golang-migrate's per-(database, schema) advisory lock; Version reads do not.

Types

type Source

type Source struct {
	// Name labels the source in logs and errors (e.g. "core", "vector").
	Name string
	// Schema is the Postgres schema the track lives in. Empty means the
	// connection's default schema (resolved via search_path / current_schema),
	// which is what the built-in tracks use. A non-empty value scopes the
	// tracking table and migration objects to that schema: the orchestrator
	// creates it (CREATE SCHEMA IF NOT EXISTS) and sets search_path on the
	// connection. Schema is treated as an untrusted identifier and validated.
	//
	// When Schema is empty (the built-in tracks), the DSN is left untouched:
	// the connection keeps the server's default search_path ("$user", public), so
	// migration objects and the tracking table land in public exactly as before
	// this orchestrator existed. The schema handling below applies only when
	// Schema is set.
	//
	// When Schema is set, search_path is pinned to it alone (pg_catalog is always
	// implicitly searched, so built-in types and functions still resolve). public
	// is NOT on the path, which keeps a schema-scoped track strictly isolated. A
	// migration that needs a shared extension installed in public (e.g. the
	// pgvector "vector" type) must therefore either install/relocate the extension
	// into this schema or schema-qualify the reference; it cannot rely on public.
	//
	// Do not register two sources whose schemas resolve to the same value with the
	// same TrackingTable — e.g. one source with Schema == "" and another naming the
	// connection's current_schema() explicitly. They would share one tracking-table
	// row and one advisory lock and corrupt each other's state. The collision unit
	// is (resolved schema, TrackingTable). validateSources catches collisions on the
	// literal Schema; RunUp additionally resolves "" to current_schema() and rejects
	// collisions that only appear after resolution.
	Schema string
	// TrackingTable is the golang-migrate bookkeeping table for this track.
	TrackingTable string
	// FS holds the embedded migration files.
	FS fs.FS
	// Dir is the subdirectory within FS that holds this track's files.
	Dir string
	// PreCheck, if set, runs before any source is applied. A non-nil error
	// aborts the whole run before any migration executes (fail-fast).
	PreCheck func(url string) error
}

Source describes one migration track for the orchestrator to apply. Downstream consumers register their own Sources alongside the built-in ones rather than owning a runner, so track ordering and failure handling stay centralized.

func BuiltinSources

func BuiltinSources(vectorEnabled bool) []Source

BuiltinSources returns the built-in source set: the core track always, and the vector track when vectorEnabled. app.Start prepends these to any downstream-registered extra sources before calling RunUp, so the built-in tracks always run first and downstream consumers only supply their own extras (never assembling this slice themselves). A caller that invokes RunUp directly (e.g. a migration CLI) composes the list the same way: BuiltinSources first, then extras.

Jump to

Keyboard shortcuts

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