Documentation
¶
Index ¶
- func EffectiveFleetStatus(status, lastSeen string, threshold time.Duration) string
- func HashFleetKey(key string) string
- type DailyBalance
- type Deployment
- type EarningsRecord
- type FleetDevice
- type HealthScore
- type Store
- func (s *Store) Close() error
- func (s *Store) ConfirmFleetDeviceKey(kind, name string) error
- func (s *Store) DeleteDeployment(slug string) error
- func (s *Store) DeleteFleetDevice(id int64) error
- func (s *Store) FleetDeviceKeyState(kind, name string) (hash string, confirmed bool, err error)
- func (s *Store) GetCredentials(slug string) (map[string]string, error)
- func (s *Store) GetDeployment(slug string) (Deployment, bool, error)
- func (s *Store) GetServiceDetail(slug string) (string, error)
- func (s *Store) HealthScores(days int) map[string]HealthScore
- func (s *Store) ListCredentialSlugs() []string
- func (s *Store) ListDailyBalances(daysBack int) []DailyBalance
- func (s *Store) ListDeployments() []Deployment
- func (s *Store) ListFleetDevices() []FleetDevice
- func (s *Store) ListLatestEarnings() []EarningsRecord
- func (s *Store) ListServiceDetails() map[string]string
- func (s *Store) PurgeOldData(retentionDays int) (int64, error)
- func (s *Store) RecordEvent(slug, event, detail string)
- func (s *Store) SaveCredentials(slug string, values map[string]string) error
- func (s *Store) SaveEarnings(record EarningsRecord) (EarningsRecord, error)
- func (s *Store) SaveServiceDetail(slug, detailJSON string) error
- func (s *Store) SetFleetDeviceKey(kind, name, hash string) error
- func (s *Store) SweepStaleFleetDevices(offlineAfter, reapAfter time.Duration) (offlined int64, reaped int64, err error)
- func (s *Store) UpsertDeployment(dep Deployment) error
- func (s *Store) UpsertFleetDevice(device FleetDevice) (FleetDevice, error)
- func (s *Store) UpsertFleetHeartbeat(device FleetDevice) (FleetDevice, error)
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func EffectiveFleetStatus ¶ added in v0.8.0
EffectiveFleetStatus returns the status a fleet device should DISPLAY given how long ago it last checked in. It is the read-path sibling of SweepStaleFleetDevices' SQL: an "online" device whose lastSeen is older than threshold is shown as "offline" immediately, so the Fleet view is accurate between scheduler ticks without the read path ever mutating storage. lastSeen is parsed as RFC3339 (the format the heartbeat writes); a value that does not parse (e.g. AddFleetDevice's "not connected yet", or an empty last_seen) leaves the status unchanged, as does any non-"online" status.
func HashFleetKey ¶ added in v0.10.0
HashFleetKey returns the SHA-256 hex digest of a per-worker fleet key. The desktop fleet server only verifies inbound heartbeats and issues keys (it never calls out to devices), so a one-way hash is sufficient storage at rest.
Types ¶
type DailyBalance ¶ added in v0.7.0
type Deployment ¶
type Deployment struct {
Slug string `json:"slug"`
ContainerID string `json:"containerId"`
Name string `json:"name"`
Image string `json:"image"`
Status string `json:"status"`
Runtime string `json:"runtime"`
CPUPercent float64 `json:"cpuPercent"`
MemoryMB float64 `json:"memoryMb"`
CreatedAt string `json:"createdAt"`
UpdatedAt string `json:"updatedAt"`
}
type EarningsRecord ¶
type FleetDevice ¶ added in v0.7.0
type FleetDevice struct {
ID int64 `json:"id"`
Name string `json:"name"`
Kind string `json:"kind"`
Endpoint string `json:"endpoint"`
OS string `json:"os"`
Arch string `json:"arch"`
Status string `json:"status"`
Services []string `json:"services"`
LastSeen string `json:"lastSeen"`
CreatedAt string `json:"createdAt"`
}
type HealthScore ¶ added in v0.8.0
type HealthScore struct {
Score int `json:"score"`
UptimePercent float64 `json:"uptimePercent"`
Samples int `json:"samples"`
Restarts int `json:"restarts"`
Crashes int `json:"crashes"`
Stops int `json:"stops"`
}
HealthScore is one service's rolling health over the query window: a 0-100 Score, the uptime percentage it was blended from, and the raw event counts the score penalises. Samples is the number of health_up/health_down datapoints in the window; a service with lifecycle events but no samples yet (uptime sampling has not run) reports Samples==0 and a Score equal to its event-score, so it is not dragged to 0 merely for lacking sampling data.
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
func (*Store) ConfirmFleetDeviceKey ¶ added in v0.10.0
ConfirmFleetDeviceKey marks a device's key confirmed — it has authenticated with its own key, so the shared bootstrap key is refused for it from now on.
func (*Store) DeleteDeployment ¶
func (*Store) DeleteFleetDevice ¶ added in v0.7.0
func (*Store) FleetDeviceKeyState ¶ added in v0.10.0
FleetDeviceKeyState returns the stored per-worker key hash and confirmed flag for the device identified by (kind, name). hash is "" when the device has no key yet (unenrolled).
func (*Store) GetCredentials ¶
func (*Store) GetDeployment ¶
func (s *Store) GetDeployment(slug string) (Deployment, bool, error)
func (*Store) GetServiceDetail ¶ added in v0.9.0
GetServiceDetail returns the stored JSON detail blob for a slug, or "" (and no error) when the slug has no detail row yet — an absent detail is a normal state, not a failure, mirroring GetCredentials' empty-map-on-ErrNoRows contract.
func (*Store) HealthScores ¶ added in v0.8.0
func (s *Store) HealthScores(days int) map[string]HealthScore
HealthScores computes a 0-100 health score per service from the runtime_events written over the last `days` days, keyed by slug. It adapts the production CashPilot health formula to the Desktop's event vocabulary:
- event-score: start at 100, then -5 per restart (a "restarted" event), -20 per crash (any "*_error" or "missing_from_runtime"), -2 per stop (a "stopped" event); floored at 0 (and capped at 100, a no-op while subtracting).
- uptime%: health_up / (health_up + health_down) * 100 over the window, from the per-cycle up/down sampling. Zero samples -> 0.
- final score: once there is at least one uptime sample, blend 40% event-score with 60% uptime% (full-precision uptime, as the original does); with NO samples yet the score is the event-score alone, so a service is not punished to 0 merely because sampling has not produced data.
runtime_events.created_at is written as datetime('now') ("YYYY-MM-DD HH:MM:SS", UTC), so the window is compared against datetime('now', '-N days') in that same format — NOT the RFC3339Nano earnings uses. Only slugs with at least one event in the window appear in the returned map.
func (*Store) ListCredentialSlugs ¶ added in v0.7.0
ListCredentialSlugs returns the slug of every service that has saved credentials, ordered by slug. collectAll unions this with the deployment set so imageless supported services (which never create a deployment row) still participate in the scheduled collection cycle.
func (*Store) ListDailyBalances ¶ added in v0.7.0
func (s *Store) ListDailyBalances(daysBack int) []DailyBalance
ListDailyBalances returns the latest successful balance (rows whose error column is empty) for each (platform, day) over the last daysBack days. The latest row per (platform, day) is chosen by MAX(id), not MAX(created_at): created_at is stored as RFC3339Nano whose variable-length fraction makes a lexicographic MAX(created_at) mis-order same-second rows (e.g. "…:00Z" sorts AFTER "…:00.5Z" because 'Z' > '.'), so the monotonic AUTOINCREMENT id is the deterministic "last written wins" key.
func (*Store) ListDeployments ¶
func (s *Store) ListDeployments() []Deployment
func (*Store) ListFleetDevices ¶ added in v0.7.0
func (s *Store) ListFleetDevices() []FleetDevice
func (*Store) ListLatestEarnings ¶
func (s *Store) ListLatestEarnings() []EarningsRecord
ListLatestEarnings returns the most recently written row per platform, INCLUDING error rows (the dashboard breakdown and notifications rely on the latest row even when it failed). The latest row per platform is chosen by MAX(id), not MAX(created_at): created_at is RFC3339Nano whose variable-length fraction makes a lexicographic MAX(created_at) mis-order same-second rows (e.g. "…:00Z" sorts ABOVE "…:00.5Z" because 'Z' > '.'), so the monotonic AUTOINCREMENT id is the deterministic "last written wins" key — matching the shape ListDailyBalances already uses.
func (*Store) ListServiceDetails ¶ added in v0.9.0
ListServiceDetails returns every stored per-service detail blob keyed by slug, so GetAppState can hand the frontend all detail documents in one read. A query or scan error yields an empty (non-nil) map rather than failing, matching the best-effort intent of the other list methods; callers can always range over the result safely.
func (*Store) PurgeOldData ¶ added in v0.8.0
PurgeOldData deletes earnings and runtime_events rows older than the cutoff, but NEVER the most-recent earnings row per platform (so ListLatestEarnings and the dashboard breakdown keep working for a service that hasn't updated in a long time). Returns the number of rows deleted. A retentionDays <= 0 is a no-op (retention disabled).
func (*Store) RecordEvent ¶
func (*Store) SaveCredentials ¶
func (*Store) SaveEarnings ¶
func (s *Store) SaveEarnings(record EarningsRecord) (EarningsRecord, error)
func (*Store) SaveServiceDetail ¶ added in v0.9.0
SaveServiceDetail upserts a per-service JSON detail blob keyed by slug. It is a generic sidecar to the flat earnings row: any collector can stash a JSON document (e.g. the MystNodes per-node earnings breakdown) alongside its balance without widening the earnings schema. The blob is stored verbatim — the collector owns its shape and the frontend parses it — so this method never inspects detailJSON.
func (*Store) SetFleetDeviceKey ¶ added in v0.10.0
SetFleetDeviceKey stores a device's per-worker key hash and marks it unconfirmed (the device confirms by authenticating with the key later). It errors if the device row does not exist, so a caller never hands a client a key that was not actually persisted (which would lock that client out).
func (*Store) SweepStaleFleetDevices ¶ added in v0.8.0
func (s *Store) SweepStaleFleetDevices(offlineAfter, reapAfter time.Duration) (offlined int64, reaped int64, err error)
SweepStaleFleetDevices ages fleet devices out of the online set as heartbeats stop arriving, mirroring production CashPilot's device lifecycle: a device whose last_seen is older than offlineAfter is flipped to "offline" (the ~180s / 3-missed-heartbeat grace), and one already "offline" whose last_seen is older than reapAfter is deleted (the ~1h reap). It returns how many rows were offlined and how many were reaped.
last_seen is written by UpsertFleetHeartbeat / fleet_server as an RFC3339 timestamp WITHOUT a fractional part, so it is fixed-length and UTC; formatting the cutoffs the same way makes the lexicographic string comparison a correct chronological order. A non-timestamp placeholder such as AddFleetDevice's "not connected yet" sorts above any real cutoff, so a never-connected device is never swept.
func (*Store) UpsertDeployment ¶
func (s *Store) UpsertDeployment(dep Deployment) error
func (*Store) UpsertFleetDevice ¶ added in v0.7.0
func (s *Store) UpsertFleetDevice(device FleetDevice) (FleetDevice, error)
func (*Store) UpsertFleetHeartbeat ¶ added in v0.7.0
func (s *Store) UpsertFleetHeartbeat(device FleetDevice) (FleetDevice, error)