Documentation
¶
Overview ¶
Package sql is the SQL provider (ADR-0232, FEAT-0011): the SQLDatabase reconciler, which deploys one rqlite engine per database through the add-on runtime with durable storage (ADR-0231), the engine password, the in-process registry of Ready engines, and the engine client. Imported as sqlsvc.
Index ¶
- Constants
- func ChangeToken(master []byte, ns v1.NamespaceName, name v1.ObjectName) string
- func EnginePassword(master []byte, ns v1.NamespaceName, name v1.ObjectName) string
- type Backups
- func (b Backups) Empty(ctx context.Context, ns v1.NamespaceName, name v1.ObjectName) error
- func (b Backups) HasTables(ctx context.Context, ns v1.NamespaceName, name v1.ObjectName) (bool, error)
- func (b Backups) Load(ctx context.Context, ns v1.NamespaceName, name v1.ObjectName, file io.Reader) error
- func (b Backups) Source(ctx context.Context, ns v1.NamespaceName, name v1.ObjectName) (io.ReadCloser, error)
- type Engines
- type Facade
- func (f *Facade) CheckRead(ctx context.Context, ns v1.NamespaceName, fn v1.ObjectName, alias string) error
- func (f *Facade) Execute(ctx context.Context, ns v1.NamespaceName, fn v1.ObjectName, binding string, ...) ([]local.ExecResult, error)
- func (f *Facade) Query(ctx context.Context, ns v1.NamespaceName, fn v1.ObjectName, binding string, ...) ([]local.QueryResult, error)
- type FacadeDeps
- type Feed
- type FeedDeps
- type MetaReader
- type Prober
- type Reconciler
- func (r *Reconciler) Backups() Backups
- func (r *Reconciler) Engines() *Engines
- func (r *Reconciler) MapFunction(ctx context.Context, obj v1.Object) []controller.Request
- func (r *Reconciler) MapRestore(_ context.Context, obj v1.Object) []controller.Request
- func (r *Reconciler) Orphans(ctx context.Context) ([]v1.ObjectRef, error)
- func (r *Reconciler) Prober() Prober
- func (r *Reconciler) ReclaimOrphans(ctx context.Context) error
- func (r *Reconciler) Reconcile(ctx context.Context, req controller.Request) (controller.Result, error)
- type ReconcilerDeps
- type Resolver
- type Watermarks
Constants ¶
const ( ReasonEngineNotReady = "EngineNotReady" ReasonEngineConvergeFailed = "EngineConvergeFailed" ReasonNoDirectory = "NoDirectory" ReasonRestored = "Restored" )
The Ready reasons a SQLDatabase reports when False, and the reasons of DataMissing.
const DefaultCallTimeout = 30 * time.Second
DefaultCallTimeout bounds one SQL call when sql.callTimeout is unset (ADR-0233 Decision 4).
const (
Runtime = "rqlite"
)
The engine's fixed shape (ADR-0232 Decisions 2 and 3).
Variables ¶
This section is empty.
Functions ¶
func ChangeToken ¶
func ChangeToken(master []byte, ns v1.NamespaceName, name v1.ObjectName) string
ChangeToken is a database's change feed capability (ADR-0235 Decision 2): HMAC-SHA256 of the node master over "funcd-sql-cdc/<ns>/<name>", base64url. Nothing stores it.
func EnginePassword ¶
func EnginePassword(master []byte, ns v1.NamespaceName, name v1.ObjectName) string
EnginePassword derives a database's engine password from the node master (ADR-0232 Decision 5): HMAC-SHA256 over "funcd-sql-engine/<ns>/<name>", base64url. Nothing stores it; a master rotation changes it at the next engine start.
Types ¶
type Backups ¶
type Backups struct {
Engines *Engines
Master []byte
Client *http.Client // nil ⇒ a node client with no timeout, bounded by each call's context; share one
}
Backups copies and loads databases through their engines for workload backups (ADR-0234): Source is workload.Sources.SQL, and Backups implements the backup service's SQLLoader. Neither holds a whole database in memory.
func (Backups) Empty ¶
func (b Backups) Empty(ctx context.Context, ns v1.NamespaceName, name v1.ObjectName) error
Empty leaves a database with no table, view, index or trigger, by loading an empty SQLite file through /db/load.
func (Backups) HasTables ¶
func (b Backups) HasTables(ctx context.Context, ns v1.NamespaceName, name v1.ObjectName) (bool, error)
HasTables reports whether a database holds a table, view, index or trigger, the restore's emptiness rule.
func (Backups) Load ¶
func (b Backups) Load(ctx context.Context, ns v1.NamespaceName, name v1.ObjectName, file io.Reader) error
Load replaces all of a database's data with the SQLite file read from file: Empty, then the file streamed to rqlite's /boot. /db/load was killed for its memory near 100 MB under the default 256Mi bound, where /boot stays near 12 MiB (rqlite 10.5.3, checked 2026-10-12), so this is ADR-0234 Decision 3's switch.
func (Backups) Source ¶
func (b Backups) Source(ctx context.Context, ns v1.NamespaceName, name v1.ObjectName) (io.ReadCloser, error)
Source streams a database's SQLite file in DELETE mode, one self-contained file (ADR-0234 Decision 2). Its reader fails, instead of reaching io.EOF, when the engine sets the stream-error trailer.
type Engines ¶
type Engines struct {
// contains filtered or unexported fields
}
Engines is the in-process registry of Ready engines' addresses (ADR-0232 Decision 6), filled by the reconciler and read by the deletion probe and the access facade. Safe for concurrent use.
func (*Engines) Address ¶
func (e *Engines) Address(ns v1.NamespaceName, name v1.ObjectName) (string, bool)
Address returns a Ready engine's address.
func (*Engines) Delete ¶
func (e *Engines) Delete(ns v1.NamespaceName, name v1.ObjectName)
Delete forgets an engine that is not Ready or is deleted.
func (*Engines) Set ¶
func (e *Engines) Set(ns v1.NamespaceName, name v1.ObjectName, addr string)
Set records a Ready engine's address.
type Facade ¶
type Facade struct {
// contains filtered or unexported fields
}
Facade resolves a caller's alias, asks Cedar, and calls the database's engine as user funcd. It implements local.SQL and health.ReadChecker.
func NewFacade ¶
func NewFacade(d FacadeDeps) (*Facade, error)
NewFacade builds the facade; Resolver, Authorizer, Engines and Master are required.
func (*Facade) CheckRead ¶
func (f *Facade) CheckRead(ctx context.Context, ns v1.NamespaceName, fn v1.ObjectName, alias string) error
CheckRead resolves the alias, asks sql::read and checks that the engine is Ready, with no engine call: the dependency check of a binding (ADR-0233 Decision 8). A missing engine wraps local.ErrEngineNotReady.
func (*Facade) Execute ¶
func (f *Facade) Execute(ctx context.Context, ns v1.NamespaceName, fn v1.ObjectName, binding string, stmts []json.RawMessage) ([]local.ExecResult, error)
Execute runs statements in one transaction on /db/execute (ADR-0233): sql::read and sql::write, since RETURNING reads; one failed statement applies none.
func (*Facade) Query ¶
func (f *Facade) Query(ctx context.Context, ns v1.NamespaceName, fn v1.ObjectName, binding string, stmts []json.RawMessage) ([]local.QueryResult, error)
Query runs read-only statements on /db/query (ADR-0233): sql::read, and a write is refused by the engine.
type FacadeDeps ¶
type FacadeDeps struct {
Resolver Resolver
Authorizer auth.Authorizer
Engines *Engines
Master []byte
HTTPClient *http.Client // nil ⇒ a node client bounded by CallTimeout
CallTimeout time.Duration // 0 ⇒ DefaultCallTimeout
Logger *slog.Logger
}
FacadeDeps configures the SQL facade, the PEP of every context.sql call (ADR-0233 Decision 4).
type Feed ¶
type Feed struct {
// contains filtered or unexported fields
}
Feed receives the changes every engine posts and turns those an EventSource names into named CloudEvents (ADR-0235). It reads the databases and EventSources from the store on each delivery, so it holds no registry; its boot gate stays closed until Loaded, so no change is published before the Sensors that act on it subscribe.
func (*Feed) Handler ¶
Handler is POST /v1/changes/{token}. The path, which carries the token, is never logged.
func (*Feed) Loaded ¶
func (f *Feed) Loaded()
Loaded opens the boot gate: the Sensors present at the start have subscribed, so an event the feed publishes reaches them. Until then every delivery with a valid token answers 503 and rqlite retries it.
func (*Feed) Serve ¶
Serve listens on host:port, retrying each second until the address exists (the bridge appears with the first worker), and serves the feed until ctx is done.
func (*Feed) URL ¶
func (f *Feed) URL(host string, port int) func(ns v1.NamespaceName, name v1.ObjectName) string
URL is the endpoint a database's engine posts its changes to, on host:port.
type FeedDeps ¶
type FeedDeps struct {
Store store.Store
Publisher eventing.Publisher
Watermarks Watermarks
Master []byte
Hold hold.Gate // nil ⇒ never held
NamespaceHold hold.NamespaceGate // nil ⇒ no namespace held
Logger *slog.Logger
}
FeedDeps configures the change feed; Store, Publisher, Watermarks and Master are required.
type MetaReader ¶
type MetaReader interface {
Get(ctx context.Context, gvk v1.GroupVersionKind, ns v1.NamespaceName, name v1.ObjectName) (v1.Object, error)
}
MetaReader is the read-only metastore view the resolver needs.
type Prober ¶
type Prober struct {
Engines *Engines
Master []byte
Volumes provider.Volumes
Client *http.Client // nil ⇒ a node client with a 5 s timeout
}
Prober answers the deletion protection's question (ADR-0232 Decision 7): does a database's engine hold a user table?
func (Prober) HasTables ¶
func (p Prober) HasTables(ctx context.Context, ns v1.NamespaceName, name v1.ObjectName) (bool, error)
HasTables reports whether the engine holds a user table. With no Ready engine it answers false when the database has no directory (nothing was ever written) and fails Unavailable when it has one (fail closed).
type Reconciler ¶
type Reconciler struct {
// contains filtered or unexported fields
}
Reconciler is the controller.Reconciler for KindSQLDatabase.
func NewReconciler ¶
func NewReconciler(d ReconcilerDeps) (*Reconciler, error)
NewReconciler builds the reconciler. Store, Provider, Engines and Master are required, and Provider must implement provider.Volumes, else Invalid.
func (*Reconciler) Backups ¶
func (r *Reconciler) Backups() Backups
Backups copies and loads databases over this reconciler's engines, for workload backups (ADR-0234).
func (*Reconciler) Engines ¶
func (r *Reconciler) Engines() *Engines
Engines is the registry of Ready engines the reconciler fills.
func (*Reconciler) MapFunction ¶
func (r *Reconciler) MapFunction(ctx context.Context, obj v1.Object) []controller.Request
MapFunction maps a Function change to the databases of its namespace, whose binding counts it may change.
func (*Reconciler) MapRestore ¶
func (r *Reconciler) MapRestore(_ context.Context, obj v1.Object) []controller.Request
MapRestore maps a Restore to the databases it loads, whose DataMissing it may clear.
func (*Reconciler) Orphans ¶
Orphans returns the engines whose directory has no SQLDatabase, for hold status (ADR-0232 Decision 7).
func (*Reconciler) Prober ¶
func (r *Reconciler) Prober() Prober
Prober answers the deletion protection over this reconciler's engines and storage.
func (*Reconciler) ReclaimOrphans ¶
func (r *Reconciler) ReclaimOrphans(ctx context.Context) error
ReclaimOrphans removes, before the controller runs, the directory of every engine with no SQLDatabase left; a no-op while the platform is held, whose hold status lists them instead.
func (*Reconciler) Reconcile ¶
func (r *Reconciler) Reconcile(ctx context.Context, req controller.Request) (controller.Result, error)
Reconcile converges one SQLDatabase: deleted ⇒ tear the engine down and reclaim its directory unless held; else converge its engine, record a Ready engine's address, and write the status only when it changed.
type ReconcilerDeps ¶
type ReconcilerDeps struct {
Store store.Store
Provider provider.Runtime // OwnerKind SQLDatabase; must implement provider.Volumes
Engines *Engines
Master []byte
ImageFor func(runtime string) string
Hold hold.Gate // nil ⇒ never held
Logger *slog.Logger
SupervisionPeriod time.Duration
// ChangeFeedURL is the endpoint each engine posts its changes to (ADR-0235 Decision 1); nil ⇒ no change feed.
ChangeFeedURL func(ns v1.NamespaceName, name v1.ObjectName) string
// Watermarks are the change feed's, dropped with a deleted database; nil ⇒ none.
Watermarks Watermarks
// DurableStorage is engine storage that outlives a daemon start: only then does a missing directory mean lost
// data (DataMissing). False with no storage root or with storage.mode memory.
DurableStorage bool
}
ReconcilerDeps configures the SQLDatabase reconciler (ADR-0232).
type Resolver ¶
type Resolver interface {
Resolve(ctx context.Context, ns v1.NamespaceName, fn v1.ObjectName, alias string) (v1.ObjectName, error)
}
Resolver maps a caller's alias to the database its spec.sql binds (ADR-0233 Decision 4). The binding is the read grant, so a missing alias is Forbidden.
func NewResolver ¶
func NewResolver(r MetaReader) (Resolver, error)
NewResolver builds the metastore-backed Resolver.
type Watermarks ¶
type Watermarks interface {
Get(ctx context.Context, ns v1.NamespaceName, database v1.ObjectName, epoch string) (uint64, error)
Set(ctx context.Context, ns v1.NamespaceName, database v1.ObjectName, epoch string, index uint64) error
Delete(ctx context.Context, ns v1.NamespaceName, database v1.ObjectName) error
}
Watermarks keeps, per database and engine epoch, the highest Raft index whose events were published (ADR-0235 Decision 3); the event store's ChangeWatermarks implements it.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package engineargs builds the rqlited command line and auth file for a SQL database's engine (ADR-0232 Decision 4), shared by the container entrypoint (cmd/funcd-rqlite) and the funcdctl dev engine (ADR-0237 Decision 2) so the two cannot drift.
|
Package engineargs builds the rqlited command line and auth file for a SQL database's engine (ADR-0232 Decision 4), shared by the container entrypoint (cmd/funcd-rqlite) and the funcdctl dev engine (ADR-0237 Decision 2) so the two cannot drift. |