Files
ITWorx-Pulse-Public/internal/unraid/pools.go
T
ITWorx Pulse release export bd774932d5
Public source validation / validate (push) Failing after 3m8s
Publish ITWorx Pulse source
2026-09-03 02:09:19 +02:00

70 lines
2.2 KiB
Go

package unraid
import (
"context"
"errors"
"strings"
"time"
"github.com/itworx/pulse/internal/pool"
)
// PoolSource maps only cache records that carry filesystem totals. Unraid 7.2
// exposes one such aggregate record per named pool; the remaining member
// devices have null filesystem fields. This avoids inferring membership from
// device names while still preserving the API's truthful pool boundary.
type PoolSource struct {
Client *Client
Now func() time.Time
}
func (s PoolSource) Snapshot(ctx context.Context) (pool.RawSnapshot, error) {
doc, now, err := (ArraySource{Client: s.Client, Now: s.Now}).document(ctx)
if err != nil {
return pool.RawSnapshot{}, err
}
items := make([]pool.RawPool, 0, len(doc.Array.Caches))
for _, item := range doc.Array.Caches {
if len(item.FSSize) == 0 || string(item.FSSize) == "null" {
continue
}
total, err := rawUint(item.FSSize)
if err != nil || total == 0 || strings.TrimSpace(item.Name) == "" {
return pool.RawSnapshot{}, errors.New("Unraid pool identity or capacity is invalid")
}
used, err := rawUint(item.FSUsed)
if err != nil || used > total {
return pool.RawSnapshot{}, errors.New("Unraid pool usage is invalid")
}
items = append(items, pool.RawPool{
ID: identity(item.ID, item.Name),
Name: item.Name,
Filesystem: item.FSType,
State: poolState(item.Status),
UsableBytes: kilobytes(total),
UsedBytes: kilobytes(used),
Capabilities: pool.Capabilities{
Members: pool.CapabilityUnsupported,
Capacity: pool.CapabilityAvailable,
Redundancy: pool.CapabilityUnsupported,
Scrub: pool.CapabilityUnsupported,
FilesystemErrors: pool.CapabilityUnsupported,
Performance: pool.CapabilityUnsupported,
SSDWear: pool.CapabilityUnsupported,
MoverSignals: pool.CapabilityUnsupported,
},
})
}
if len(items) > 64 {
return pool.RawSnapshot{}, errors.New("Unraid pool response exceeds bounds")
}
return pool.RawSnapshot{Source: pool.Source{ID: "unraid", Type: "unraid"}, Pools: items, ObservedAt: now, ReceivedAt: now}, nil
}
func poolState(value string) string {
if strings.EqualFold(strings.TrimSpace(value), "DISK_OK") {
return pool.StateHealthy
}
return pool.StateUnknown
}