Documentation
¶
Overview ¶
Package capabilities provides auto-detection and manual override of sqi-worker host capabilities reported to sqi-server at registration time.
Design ¶
Hardware queries are abstracted behind the Probe interface so tests can inject controlled return values without touching real OS APIs. The default production implementation ([DefaultProbe]) calls the real syscalls via platform-specific files (probe_linux.go, probe_darwin.go, probe_windows.go).
Usage ¶
caps := capabilities.Detect(nil) // nil → DefaultProbe caps.MergeManualTags(cfg.Worker.CapabilityTags) // caps is now ready to embed in a protocol.RegisterMsg
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ValidateTagKeys ¶
ValidateTagKeys returns an error if any two capability tag keys collide case-insensitively. Tag keys are the trailing segment of an OpenJD capability name (attr.worker.tag.<key>), which the spec defines as case-insensitive, so two keys differing only in case are the same capability and would match ambiguously. Rejecting them at registration keeps the advertised tag set unambiguous.
Types ¶
type Capabilities ¶
type Capabilities struct {
// OS is the operating system name as reported by runtime.GOOS:
// "linux", "darwin", or "windows".
OS string
// OSVersion is the human-readable OS release string, e.g. "22.04" on
// Ubuntu or "14.5" on macOS. Empty if detection fails.
OSVersion string
// CPUCount is the number of logical (hardware-thread) CPUs available.
CPUCount int
// RAMMb is total installed physical RAM in mebibytes.
// 0 if detection fails.
RAMMb int
// GPU describes the GPU(s) installed on the host. Zero value means no
// GPU was detected or detection is not supported on this platform.
GPU GPUInfo
// Tags holds arbitrary string capability tags merged from auto-detection
// and any manual overrides supplied via WorkerConfig.Worker.CapabilityTags.
// The map value is the empty string for presence-only, list-style tags
// (e.g. "maya-2025") and the right-hand side of the entry for key=value
// tags (e.g. "maya=true" → Tags["maya"] = "true"). See [MergeManualTags].
//
// Auto-detected entries seeded by [Detect]:
// "os" → Capabilities.OS
// "os_version" → Capabilities.OSVersion (omitted when empty)
Tags map[string]string
}
Capabilities holds the merged set of auto-detected and manually overridden worker host capabilities.
func BuildWorkerCapabilities ¶ added in v0.2.0
func BuildWorkerCapabilities(cfg CapabilitiesConfig, manualTags []string, env CheckEnv) (Capabilities, error)
BuildWorkerCapabilities detects host capabilities, applies built-in + custom detectors, merges manual tags (which win), and validates the tag key set.
func Detect ¶
func Detect(p Probe) Capabilities
Detect auto-detects host capabilities using p. If p is nil, DefaultProbe is used. The returned Capabilities.Tags map is always non-nil and pre-populated with the "os" tag and, when non-empty, the "os_version" tag.
func (*Capabilities) ApplyDetectors ¶ added in v0.2.0
func (c *Capabilities) ApplyDetectors(detectors []Detector, env CheckEnv)
ApplyDetectors evaluates each detector against env and records emitted tags with value "true" (matching the manual `tag=true` convention used by the scheduler's attribute matcher) without overwriting keys already present.
func (*Capabilities) MergeManualTags ¶
func (c *Capabilities) MergeManualTags(tags []string)
MergeManualTags merges manual capability tags from WorkerConfig.Worker.CapabilityTags into c.Tags. Each entry is either:
- a bare tag, stored as a map key with an empty value, signaling presence (e.g. "maya-2025", "gpu", "highram"); or
- a "key=value" pair, split on the first "=" (e.g. "maya=true" sets Tags["maya"] = "true"; a value may itself contain "=", e.g. "a=b=c" sets Tags["a"] = "b=c"; a trailing "=" with nothing after it, e.g. "maya=", sets Tags["maya"] = "", same as the presence-only form).
An entry with an empty key (starting with "=", e.g. "=true") is skipped rather than stored verbatim, since an empty tag key can never be matched by an OpenJD attr.worker.tag.<key> requirement.
Manual tags always overwrite any auto-detected tag with the same key, so operators can suppress or replace an auto-detected value if needed.
type CapabilitiesConfig ¶ added in v0.2.0
type CapabilitiesConfig struct {
Detect []Detector `yaml:"detect"`
Disable []string `yaml:"disable"`
}
CapabilitiesConfig is the worker's capability-detection configuration.
type Check ¶ added in v0.2.0
type Check struct {
Exe string `yaml:"exe"`
PathGlob string `yaml:"path_glob"`
Env EnvCheck `yaml:"env"`
Registry string `yaml:"registry"`
OS string `yaml:"os"`
}
Check is a single declarative probe. Exactly one of Exe/PathGlob/Env/Registry must be set. OS optionally gates the check to one platform.
type CheckEnv ¶ added in v0.2.0
type CheckEnv interface {
LookPath(file string) (string, bool)
Glob(pattern string) []string
Getenv(key string) (string, bool)
RegistryExists(key string) bool
GOOS() string
}
CheckEnv abstracts the host queries a detector needs, so tests inject fakes.
func OSCheckEnv ¶ added in v0.2.0
func OSCheckEnv() CheckEnv
OSCheckEnv returns the production CheckEnv backed by real OS queries.
type Detector ¶ added in v0.2.0
type Detector struct {
Tag string `yaml:"tag"`
Checks []Check `yaml:"checks"`
Version VersionSpec `yaml:"version"`
Origin string `yaml:"-"` // "builtin:<name>" or "custom"; for diagnostics
}
Detector emits a presence tag (and versioned variants) when any check matches.
func BuiltinDetectors ¶ added in v0.2.0
BuiltinDetectors parses and validates the embedded built-in detectors.
func LoadDetectors ¶ added in v0.2.0
func LoadDetectors(cfg CapabilitiesConfig) ([]Detector, error)
LoadDetectors returns the active detectors: built-ins not named in cfg.Disable, followed by validated custom detectors from cfg.Detect.
func (Detector) Evaluate ¶ added in v0.2.0
Evaluate runs the detector's checks against env and returns the presence tags to advertise: the bare Tag if any check matched, plus Tag-<version> for each distinct version captured. Results are de-duplicated and sorted.
Evaluate assumes d has already passed Validate (in particular that Version.From and every check's Env.Matches compile); callers (the capability-detection loaders) validate detectors before evaluating them.
type EnvCheck ¶ added in v0.2.0
EnvCheck matches an environment variable by presence and optional value regex.
type GPUInfo ¶
type GPUInfo struct {
Vendor string
Model string
// VRAMMb is the total VRAM of the first / primary GPU in mebibytes.
VRAMMb int
Count int
}
GPUInfo describes GPU hardware available on a worker host. It mirrors [protocol.GPUInfo] so callers can convert directly; defined here to avoid an import cycle between the capabilities and protocol packages.
type Probe ¶
type Probe interface {
// OS returns the operating system identifier (runtime.GOOS equivalent).
OS() string
// OSVersion returns a human-readable OS release string. Returns an empty
// string when version detection is not supported or fails.
OSVersion() string
// CPUCount returns the number of logical CPUs.
CPUCount() int
// RAMMb returns total physical RAM in mebibytes. Returns 0 on failure.
RAMMb() int
// GPUInfo returns GPU hardware information. Returns a zero GPUInfo when no
// GPU is detected or detection is not supported.
GPUInfo() GPUInfo
}
Probe abstracts OS-level hardware queries so tests can inject fake values. All methods must be safe to call concurrently.
type VersionSpec ¶ added in v0.2.0
type VersionSpec struct {
From string `yaml:"from"`
}
VersionSpec extracts a version string from a matched signal via a regex whose named group "v" (or first capturing group) is the version.