Documentation
¶
Overview ¶
Package fleet manages many SQLite databases as a single unit: discovery from Turso orgs and Cloudflare D1 accounts, baseline capture, and parallel drift detection across the whole fleet.
Index ¶
- Constants
- func Hash(s *schema.Schema) string
- func SendHealthAlert(webhookURL string, r *HealthReport) error
- type BlastGroup
- type CheckResult
- type Config
- func (c *Config) Active() []Database
- func (c *Config) BaselineDir() string
- func (c *Config) BaselinePath(db Database) string
- func (c *Config) Filter(tag string) []Database
- func (c *Config) Merge(incoming []Database) (added, updated int)
- func (c *Config) Save(path string) error
- func (c *Config) SetQuarantine(names []string, quarantined bool) int
- type ConvergeClusterPlan
- type ConvergePlan
- type DBState
- type Database
- type FingerprintCluster
- type FingerprintError
- type FingerprintReport
- type FleetReport
- type HealthReport
- type HealthResult
- type RecoverOptions
- type RecoverReport
- type RecoverResult
- type RecoverState
- type RolloutOptions
- type RolloutReport
- type RolloutResult
- type SnapshotResult
Constants ¶
const DefaultConfigFile = "litescope.fleet.yaml"
DefaultConfigFile is the conventional fleet config name.
Variables ¶
This section is empty.
Functions ¶
func Hash ¶
Hash returns a hex SHA-256 over a deterministic, drift-significant serialization of the schema. Order-independent: tables, columns, and indexes are all sorted so column/table declaration order does not affect the result.
func SendHealthAlert ¶
func SendHealthAlert(webhookURL string, r *HealthReport) error
SendHealthAlert POSTs a fault summary to a webhook (Slack-compatible when the URL points at Slack, otherwise generic JSON). It is a no-op when the fleet is healthy. Used by scheduled/continuous health watch.
Types ¶
type BlastGroup ¶
type BlastGroup struct {
Tag string `json:"tag"` // shared tag, e.g. "group:prod"
Total int `json:"total"` // databases carrying this tag
Faulted []string `json:"faulted"` // critically faulted members
AtRisk []string `json:"at_risk"` // healthy members of the same cohort
}
BlastGroup is a shared cohort (a tag, e.g. a Turso group) that contains at least one faulted database — so the rest of the cohort may be at risk from a shared-infrastructure problem.
func BlastRadius ¶
func BlastRadius(dbs []Database, report *HealthReport) []BlastGroup
BlastRadius groups critically faulted databases by the tags they share, so a single fault report shows the blast radius across shared infrastructure (Turso groups, regions). Only cohorts containing a fault are returned, most faults first.
type CheckResult ¶
type CheckResult struct {
Database string `json:"database"`
DSN string `json:"dsn"`
// State is one of: "ok", "drift", "no-baseline", "error".
State string `json:"state"`
Drift *monitor.DriftResult `json:"drift,omitempty"`
Err error `json:"-"`
Error string `json:"error,omitempty"`
Duration time.Duration `json:"-"`
}
CheckResult is the drift outcome for a single fleet member.
type Config ¶
type Config struct {
Version int `yaml:"version"`
Name string `yaml:"name,omitempty"`
BaselinesDir string `yaml:"baseline_dir,omitempty"` // default dir for captured baselines
Databases []Database `yaml:"databases"`
// contains filtered or unexported fields
}
Config is a fleet definition, normally stored as litescope.fleet.yaml.
func (*Config) BaselineDir ¶
BaselineDir returns the directory baselines are stored in (default: .litescope/baselines).
func (*Config) BaselinePath ¶
BaselinePath returns the baseline path for a database, computing a default under BaselineDir when the entry doesn't specify one.
func (*Config) Filter ¶
Filter returns non-quarantined databases matching the given tag, or all non-quarantined databases when tag is "". Quarantined databases are excluded from every fleet operation until cleared.
func (*Config) Merge ¶
Merge adds or updates databases by name, preserving existing baselines/tags when the incoming entry doesn't set them. Returns counts of added/updated.
type ConvergeClusterPlan ¶
type ConvergeClusterPlan struct {
ClusterID string `json:"cluster_id"`
Members []Database `json:"-"` // full entries so we have DSNs
MemberNames []string `json:"members"` // names, for JSON/display
SQL string `json:"sql"`
Statements int `json:"statements"`
Destructive bool `json:"destructive"` // drops a column/table on these DBs
Drift []diff.TableDiff `json:"drift,omitempty"`
}
ConvergeClusterPlan is the convergence work for one drifted schema cluster: the SQL that transforms every member into the canonical schema.
type ConvergePlan ¶
type ConvergePlan struct {
CanonicalID string `json:"canonical_id"`
AlreadyOK int `json:"already_ok"` // databases already matching canonical
Clusters []ConvergeClusterPlan `json:"clusters"` // drifted clusters needing convergence
TotalToConverge int `json:"total_to_converge"` // total drifted databases
Unreachable []FingerprintError `json:"unreachable,omitempty"`
}
ConvergePlan describes what it takes to bring every drifted database in the fleet back to the canonical schema.
func PlanConvergence ¶
func PlanConvergence(dbs []Database, canonical *schema.Schema, concurrency int) (*ConvergePlan, error)
PlanConvergence fingerprints the fleet and, for every cluster that differs from canonical, generates the migration SQL to converge it. When canonical is nil, the largest cluster's schema is used as the reference.
func (*ConvergePlan) HasDestructive ¶
func (p *ConvergePlan) HasDestructive() bool
HasDestructive reports whether converging any cluster would drop data.
type DBState ¶
type DBState string
DBState is the outcome for one database in a rollout.
const ( StateApplied DBState = "applied" // committed successfully StateDryRun DBState = "dry-run" // validated, rolled back StateFailed DBState = "failed" // errored; halts the rollout StateSkipped DBState = "skipped" // not attempted (rollout halted earlier) StateCanary DBState = "canary" // not attempted (canary limit reached) )
type Database ¶
type Database struct {
Name string `yaml:"name"`
DSN string `yaml:"dsn"`
Baseline string `yaml:"baseline,omitempty"` // path to the baseline snapshot
// Tags allow grouping (e.g. region, tenant) for filtered operations.
Tags []string `yaml:"tags,omitempty"`
// Quarantined marks a database as excluded from fleet operations — set by
// `fleet recover` when a faulted database cannot be restored.
Quarantined bool `yaml:"quarantined,omitempty"`
}
Database is one member of a fleet.
func DiscoverD1 ¶
DiscoverD1 lists every D1 database in a Cloudflare account and returns fleet entries with d1:// DSNs. The same API token is used for discovery and queries, so the returned DSNs are immediately usable.
func DiscoverTurso ¶
DiscoverTurso lists every database in a Turso organization via the platform API and returns fleet entries with ready-to-use turso:// DSNs.
platformToken is an org/platform API token (https://api.turso.tech). dbToken is the database auth token applied to each entry's DSN; a group-level auth token works across the whole org. When dbToken is empty, the DSN is emitted with a TOKEN placeholder for the user to fill in.
type FingerprintCluster ¶
type FingerprintCluster struct {
ID string `json:"id"` // short hash of the canonical schema serialization
Count int `json:"count"` // number of databases in this cluster
Members []string `json:"members"` // database names, sorted
IsCanonical bool `json:"is_canonical"` // true for the reference cluster (largest by default)
Drift []diff.TableDiff `json:"drift,omitempty"` // how this cluster differs from canonical; nil for canonical
// contains filtered or unexported fields
}
FingerprintCluster is a group of databases that share an identical schema.
type FingerprintError ¶
FingerprintError records a database that could not be read.
type FingerprintReport ¶
type FingerprintReport struct {
Total int `json:"total"` // databases successfully fingerprinted
Clusters []FingerprintCluster `json:"clusters"` // canonical first, then by count desc
Unreachable []FingerprintError `json:"unreachable,omitempty"`
CheckedAt time.Time `json:"checked_at"`
}
FingerprintReport is the result of fingerprinting an entire fleet.
func Fingerprint ¶
func Fingerprint(dbs []Database, concurrency int) *FingerprintReport
Fingerprint reads every database's live schema in parallel and groups them into clusters of identical schemas. The largest cluster is marked canonical; every other cluster carries a diff describing how it differs from canonical.
The fingerprint is computed over exactly the fields the diff engine treats as drift-significant (table presence, column name/type/not-null, index presence), so two databases share a fingerprint if and only if `fleet check` would report no drift between them.
type FleetReport ¶
type FleetReport struct {
Results []CheckResult `json:"results"`
CheckedAt time.Time `json:"checked_at"`
}
FleetReport aggregates per-database results.
func Check ¶
func Check(cfg *Config, dbs []Database, concurrency int) *FleetReport
Check runs a drift check across every database in parallel, comparing each live schema against its baseline snapshot. concurrency <= 0 uses the default.
func (*FleetReport) Counts ¶
func (r *FleetReport) Counts() (ok, drift, noBaseline, errCount int)
Counts returns how many databases fell into each state.
func (*FleetReport) HasProblems ¶
func (r *FleetReport) HasProblems() bool
HasProblems reports whether any database drifted or errored.
type HealthReport ¶
type HealthReport struct {
Results []HealthResult `json:"results"`
CheckedAt time.Time `json:"checked_at"`
}
HealthReport aggregates fleet-wide health, sorted worst-first.
func Health ¶
func Health(dbs []Database, deep bool, concurrency int) *HealthReport
Health inspects every database in parallel for operational faults. Local files get the full inspection (integrity, WAL bloat, fragmentation, size); remote databases (Turso, D1) report reachability only, since file-level signals require local access.
func (*HealthReport) Counts ¶
func (r *HealthReport) Counts() (ok, warning, critical int)
Counts tallies databases by severity.
func (*HealthReport) HasFaults ¶
func (r *HealthReport) HasFaults() bool
HasFaults reports whether any database is in warning or critical state.
type HealthResult ¶
type HealthResult struct {
Database string `json:"database"`
DSN string `json:"dsn"`
Report *health.Report `json:"report"`
Duration time.Duration `json:"-"`
}
HealthResult is the operational health of one fleet member.
type RecoverOptions ¶
type RecoverOptions struct {
BackupDir string // where to look for backups ("" = alongside each DB)
DryRun bool // report what would happen without restoring or quarantining
Deep bool // exhaustive integrity_check when assessing health
Quarantine bool // quarantine databases with no healthy backup
}
RecoverOptions controls a fleet recovery.
type RecoverReport ¶
type RecoverReport struct {
Results []RecoverResult `json:"results"`
DryRun bool `json:"dry_run"`
StartedAt time.Time `json:"started_at"`
}
RecoverReport aggregates a fleet recovery.
func Recover ¶
func Recover(dbs []Database, opts RecoverOptions) *RecoverReport
Recover triages the fleet and restores every critically faulted local database from its most recent *verified-healthy* backup. Databases with no healthy backup are flagged for quarantine. Bloat/warning-level issues are not recovery targets and are reported as healthy here.
Recovery only applies to local files; a faulted remote database is reported as needing manual recovery. In dry-run mode nothing is written.
func (*RecoverReport) Counts ¶
func (r *RecoverReport) Counts() (restored, quarantined, failed, healthy int)
Counts tallies databases by recovery outcome.
func (*RecoverReport) Quarantine ¶
func (r *RecoverReport) Quarantine() []string
Quarantine returns the names of databases that should be marked quarantined.
type RecoverResult ¶
type RecoverResult struct {
Database string `json:"database"`
DSN string `json:"dsn"`
State RecoverState `json:"state"`
BackupPath string `json:"backup_path,omitempty"` // backup used to restore
Detail string `json:"detail,omitempty"`
Err error `json:"-"`
Error string `json:"error,omitempty"`
Duration time.Duration `json:"-"`
}
RecoverResult is the per-database recovery record.
type RecoverState ¶
type RecoverState string
RecoverState is the outcome of attempting to recover one database.
const ( RecoverHealthy RecoverState = "healthy" // no fault — nothing to do RecoverRestored RecoverState = "restored" // restored from a verified backup RecoverQuarantined RecoverState = "quarantined" // faulted, no healthy backup — excluded from future ops RecoverFailed RecoverState = "failed" // recovery attempt errored RecoverRemote RecoverState = "remote" // remote DB faulted — needs manual recovery )
type RolloutOptions ¶
type RolloutOptions struct {
DryRun bool // validate against every database without committing
Canary int // stop after this many successful applies (0 = no canary)
BackupDir string // where local backups are written ("" = alongside each DB)
NoBackup bool // skip local backups (dry-run never backs up)
}
RolloutOptions controls a staged fleet migration.
type RolloutReport ¶
type RolloutReport struct {
Results []RolloutResult `json:"results"`
StartedAt time.Time `json:"started_at"`
DryRun bool `json:"dry_run"`
Halted bool `json:"halted"` // true when a failure stopped the rollout
}
RolloutReport aggregates a staged migration across the fleet.
func Converge ¶
func Converge(plan *ConvergePlan, opts RolloutOptions) *RolloutReport
Converge applies a convergence plan, staged and fail-closed: databases are migrated one at a time across all clusters, and the first failure halts the rollout so a bad convergence can't cascade. Reuses the same per-database safety pipeline as Rollout (backup, transaction, verification, restore).
In dry-run mode every database is validated (apply + rollback) and the run never halts early, so you see every database that would fail at once.
func Rollout ¶
func Rollout(dbs []Database, sqlText string, opts RolloutOptions) *RolloutReport
Rollout applies a migration to each database in order, stopping at the first failure so a bad migration can't cascade across the fleet.
- Local files use migrate.Apply: pre-flight integrity check, VACUUM INTO backup, single transaction, foreign-key + integrity verification, and automatic rollback/restore on failure.
- Remote databases (Turso, D1) execute via their provider API. Turso runs transactionally; D1 cannot roll back a multi-statement batch.
In dry-run mode every database is validated (apply + rollback) and the rollout never halts early, so you see which databases would fail. Otherwise the first failure halts the rollout and the remaining databases are marked skipped.
func (*RolloutReport) Counts ¶
func (r *RolloutReport) Counts() (applied, failed, skipped int)
Counts tallies databases by terminal state.
type RolloutResult ¶
type RolloutResult struct {
Database string `json:"database"`
DSN string `json:"dsn"`
State DBState `json:"state"`
Executed int `json:"executed"` // statements applied
BackupPath string `json:"backup_path,omitempty"` // local backup, if any
Provider string `json:"provider"` // local, turso, d1
Err error `json:"-"`
Error string `json:"error,omitempty"`
Duration time.Duration `json:"-"`
}
RolloutResult is the per-database record.
type SnapshotResult ¶
SnapshotResult is the baseline-capture outcome for one database.