config

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Jul 13, 2026 License: AGPL-3.0 Imports: 10 Imported by: 0

Documentation

Overview

Package config defines the sqi-server runtime configuration and provides layered loading from built-in defaults, a YAML/JSON file, SQI_* environment variables, and CLI flag overrides — in that override order.

Typical usage in the serve subcommand:

cfg, err := config.Load(flagConfigFile, config.FlagOverrides{
    LogLevel:  flagLogLevel,
    LogFormat: flagLogFormat,
    HTTPAddr:  flagHTTPAddr,
})
if err != nil {
    return err
}
if errs := config.Validate(cfg); len(errs) > 0 {
    for _, e := range errs {
        fmt.Fprintf(os.Stderr, "config error: %s: %s\n", e.Field, e.Message)
    }
    return fmt.Errorf("%d configuration error(s)", len(errs))
}

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Config

type Config struct {
	HTTP          HTTPConfig          `yaml:"http"`
	NATS          NATSConfig          `yaml:"nats"`
	Store         StoreConfig         `yaml:"store"`
	Log           LogConfig           `yaml:"log"`
	Scheduler     SchedulerConfig     `yaml:"scheduler"`
	Discovery     DiscoveryConfig     `yaml:"discovery"`
	OpenJD        OpenJDConfig        `yaml:"openjd"`
	Diagnostics   DiagnosticsConfig   `yaml:"diagnostics"`
	PresetLibrary PresetLibraryConfig `yaml:"preset_library"`
}

Config is the complete runtime configuration for sqi-server. Zero values are not valid; use DefaultConfig or Load to obtain a populated instance.

func DefaultConfig

func DefaultConfig() Config

DefaultConfig returns a Config with sensible defaults suitable for local development. Production deployments should override fields via a config file or SQI_* environment variables.

func Load

func Load(filePath string, flags FlagOverrides) (Config, error)

Load builds a Config by applying four layers in increasing precedence:

  1. Built-in defaults (DefaultConfig)
  2. YAML/JSON file at filePath, or the first file found in the default search path when filePath is empty
  3. SQI_* environment variables
  4. CLI flag overrides via flags

A missing config file is not an error unless filePath was set explicitly.

type DiagnosticsConfig

type DiagnosticsConfig struct {
	// BufferSize is the maximum diagnostic records retained per component
	// (server + each worker). 0 disables diagnostics entirely: no ring buffer,
	// no worker.diag subscription, and the REST endpoint returns 503. A positive
	// value is the per-component capacity. Default: 1000. Set to 0 to avoid
	// spending memory on something accessed out-of-band
	// (journald/Docker/Loki/etc.). Must not be negative.
	// Env: SQI_DIAGNOSTICS_BUFFER_SIZE
	BufferSize int `yaml:"buffer_size"`
}

DiagnosticsConfig controls the in-memory diagnostic-log ring buffer surfaced in the web UI.

type DiscoveryConfig

type DiscoveryConfig struct {
	// Enabled controls whether sqi-server broadcasts a _sqi._tcp mDNS record
	// on the local network. Disable in environments that forbid multicast.
	// Env: SQI_DISCOVERY_ENABLED
	Enabled bool `yaml:"enabled"`

	// InstanceName is the mDNS service instance name advertised on the
	// network. Defaults to "sqi-server".
	// Env: SQI_DISCOVERY_INSTANCE_NAME
	InstanceName string `yaml:"instance_name"`
}

DiscoveryConfig controls mDNS service advertisement.

type FlagOverrides

type FlagOverrides struct {
	// LogLevel overrides Log.Level when non-empty. Bound to --log-level.
	LogLevel string
	// LogFormat overrides Log.Format when non-empty. Bound to --log-format.
	LogFormat string
	// HTTPAddr overrides HTTP.Addr when non-empty. Bound to --http-addr.
	HTTPAddr string
	// EnforceLimits overrides OpenJD.EnforceLimits when non-nil. Bound to
	// --openjd-enforce-limits. A pointer (not a bool) so an unset flag leaves the
	// lower layers intact while an explicit --openjd-enforce-limits=false can turn
	// the (default-true) gate off.
	EnforceLimits *bool
}

FlagOverrides carries values from CLI flags that take highest precedence during config loading. Only non-empty / non-zero values override the lower layers, so callers can safely pass flag values that were not set without clobbering config-file or environment values.

type HTTPConfig

type HTTPConfig struct {
	// Addr is the TCP address the HTTP server listens on.
	// Env: SQI_HTTP_ADDR
	Addr string `yaml:"addr"`

	// EnablePprof exposes the Go runtime profiling endpoints at /debug/pprof/
	// when true. Profiling data is sensitive; never enable this on a server
	// accessible to untrusted networks. Disabled by default.
	// Env: SQI_HTTP_ENABLE_PPROF
	EnablePprof bool `yaml:"enable_pprof"`
}

HTTPConfig controls the REST and WebSocket listener.

type LogConfig

type LogConfig struct {
	// Level is the minimum log level to emit.
	// Accepted values: debug, info, warn, error.
	// Env: SQI_LOG_LEVEL
	Level string `yaml:"level"`

	// Format selects the log output format.
	// Accepted values: json, text.
	// Env: SQI_LOG_FORMAT
	Format string `yaml:"format"`
}

LogConfig controls structured log output.

type NATSConfig

type NATSConfig struct {
	// Addr is the TCP address the embedded NATS server binds to.
	// Default is loopback so external clients cannot reach it directly;
	// sqi-server communicates with NATS in-process.
	// Env: SQI_NATS_ADDR
	Addr string `yaml:"addr"`

	// DataDir is the directory used by JetStream for file-backed stream
	// storage. Created at startup if it does not exist.
	// Env: SQI_NATS_DATA_DIR
	DataDir string `yaml:"data_dir"`

	// MaxStoreMB is the JetStream file-storage cap in megabytes.
	// Env: SQI_NATS_MAX_STORE_MB
	MaxStoreMB int `yaml:"max_store_mb"`
}

NATSConfig controls the embedded NATS JetStream broker.

type OpenJDConfig

type OpenJDConfig struct {
	// EnforceLimits gates quantitative limit validation (maximum name lengths,
	// counts, reserved-name rules). Disable only when onboarding templates that
	// predate the strict limits and cannot yet be updated.
	// Env: SQI_OPENJD_ENFORCE_LIMITS
	EnforceLimits bool `yaml:"enforce_limits"`
}

OpenJDConfig controls OpenJD submission and validation behavior.

type PresetLibraryConfig added in v0.2.0

type PresetLibraryConfig struct {
	// URL is the library's JSON index URL (the raw index file, not a repo page).
	// Empty disables the feature. Default: the official sqi preset library.
	// Env: SQI_PRESET_LIBRARY_URL
	URL string `yaml:"url"`
}

PresetLibraryConfig controls the community preset library integration.

type SchedulerConfig

type SchedulerConfig struct {
	// HeartbeatTimeout is the duration after which a worker that has not sent
	// a heartbeat is declared offline and its in-flight tasks are reclaimed.
	// Env: SQI_SCHEDULER_HEARTBEAT_TIMEOUT
	HeartbeatTimeout time.Duration `yaml:"heartbeat_timeout"`

	// TickInterval is how often the assignment loop wakes to match ready tasks
	// to available workers.
	// Env: SQI_SCHEDULER_TICK_INTERVAL
	TickInterval time.Duration `yaml:"tick_interval"`

	// MaxTasksPerWorker caps the number of tasks that can be simultaneously
	// assigned to a single worker. Must be ≥ 1.
	// Env: SQI_SCHEDULER_MAX_TASKS_PER_WORKER
	MaxTasksPerWorker int `yaml:"max_tasks_per_worker"`

	// OfflineWorkerRetention is how long a worker may stay offline before the
	// retention sweep hard-deletes it, bounding worker-table growth on farms
	// with ephemeral nodes. Disabled and online workers are never auto-removed.
	// Set to 0 to disable automatic removal. Default: 24h.
	// Env: SQI_SCHEDULER_OFFLINE_WORKER_RETENTION
	OfflineWorkerRetention time.Duration `yaml:"offline_worker_retention"`

	// JobRetention is how long a terminal job is kept before the retention
	// sweep hard-deletes it and all of its data. completed and canceled jobs
	// are always eligible; failed jobs only when JobRetentionIncludeFailed is
	// set. Set to 0 to disable automatic deletion. Default: 168h (7 days).
	// Env: SQI_SCHEDULER_JOB_RETENTION
	JobRetention time.Duration `yaml:"job_retention"`

	// JobRetentionIncludeFailed extends the retention sweep to failed jobs.
	// Default: false. Env: SQI_SCHEDULER_JOB_RETENTION_INCLUDE_FAILED
	JobRetentionIncludeFailed bool `yaml:"job_retention_include_failed"`

	// UnschedulableGrace is how long a ready task may wait with no eligible
	// online worker before it is flagged unschedulable. 0 disables the sweep.
	// Default: 30s. Env: SQI_SCHEDULER_UNSCHEDULABLE_GRACE
	UnschedulableGrace time.Duration `yaml:"unschedulable_grace"`

	// DefaultMaxAttempts is the server-level fallback for the farm-wide default
	// number of attempts a task may make before going terminal-failed. It is the
	// bottom tier of the layered retry policy (Server -> Farm -> Queue -> Job).
	// Must be >= 1; 1 disables auto-retry. Default: 3.
	// Env: SQI_SCHEDULER_DEFAULT_MAX_ATTEMPTS
	DefaultMaxAttempts int `yaml:"default_max_attempts"`

	// RetryDelay is the server-level fallback default backoff before a failed
	// task re-enters the ready queue. 0 = immediate. Default: 30s.
	// Env: SQI_SCHEDULER_RETRY_DELAY
	RetryDelay time.Duration `yaml:"retry_delay"`

	// DefaultFailureLimit is the server-level fallback default job-level
	// failure ceiling. 0 = off (no auto-park). Default: 0.
	// Env: SQI_SCHEDULER_DEFAULT_FAILURE_LIMIT
	DefaultFailureLimit int `yaml:"default_failure_limit"`
}

SchedulerConfig controls the task assignment loop behavior. These fields are defined now for completeness and config file documentation; they are consumed by the scheduler component.

type StoreConfig

type StoreConfig struct {
	// SQLitePath is the path to the SQLite database file.
	// Created at startup if it does not exist.
	// Env: SQI_STORE_SQLITE_PATH
	SQLitePath string `yaml:"sqlite_path"`

	// CheckpointInterval is how often the background goroutine runs a WAL
	// checkpoint (PRAGMA wal_checkpoint(TRUNCATE)) to fold committed WAL frames
	// back into the main database file and keep the WAL from growing unboundedly.
	// Must be > 0. Set to a large value (e.g. "24h") to effectively disable
	// periodic checkpointing (a final checkpoint always runs on shutdown).
	// Env: SQI_STORE_CHECKPOINT_INTERVAL
	CheckpointInterval time.Duration `yaml:"checkpoint_interval"`
}

StoreConfig controls the embedded SQLite state store.

type ValidationError

type ValidationError struct {
	// Field is the dot-separated config path, e.g. "http.addr" or
	// "scheduler.max_tasks_per_worker". It mirrors the YAML key hierarchy.
	Field string
	// Message describes what is wrong and how to correct it.
	Message string
}

ValidationError describes a single configuration error with the field path that is invalid and an actionable message explaining how to fix it.

func Validate

func Validate(cfg Config) []ValidationError

Validate checks cfg for missing or invalid values. It returns all violations found in a single pass so callers can report every problem at once rather than failing on the first one.

A nil or empty slice means the configuration is valid.

func (ValidationError) Error

func (e ValidationError) Error() string

Jump to

Keyboard shortcuts

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