The controller grants a read only from the owner's announcement (ADR 0495 clause 3). gitea announced `bound` unreadable, so mesh-provisioner bound no forge account; disk-load announced `readings` unreadable, refused to restic, nfs-server and mounts; restic announced `good` unreadable, which the self-check reads. Nothing in the catalogue compared readers with announcements since the gate's manifest check went (clause 5). Quick fix: mark those three states readable. Thorough fix: also checks/readable, which reads every owner's Go and TypeScript announcement and refuses any `reads` of a state it does not announce readable, so the next owner to announce cannot repeat it. Chose thorough: the same kind hit three owners at once. Reads of other repositories' owners (mesh-controller.lease, mesh-grants.accounts) are not judged here.
63 lines
2.4 KiB
Go
63 lines
2.4 KiB
Go
// The disk-load module's Go bundle (novox/hq ADR 0188, ADR 0193, issue 312): a process the node's
|
|
// runtime launches and speaks MCP over stdio to. It reads the machine's storage load from /proc and
|
|
// /sys — iowait, pressure stall, each disk's busy share, throughput, IOPS, wait and queue depth, the
|
|
// filesystems' space and the processes doing the I/O — and changes nothing of the machine.
|
|
//
|
|
// It also measures the data items the modules of its node declare (ADR 0233) and keeps each reading and the item's
|
|
// seven-day peak as its own state `readings` (ADR 0571 clause 3), composed from the bus (no file).
|
|
package main
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
"time"
|
|
|
|
stdio "git.novox.be/novox/mesh-sdk/go"
|
|
"git.novox.be/novox/mesh-sdk/go/announce"
|
|
"git.novox.be/novox/mesh-sdk/go/catalogue"
|
|
"git.novox.be/novox/mesh-sdk/go/compose/frombus"
|
|
"git.novox.be/novox/mesh-sdk/go/compose/fromruntime"
|
|
)
|
|
|
|
func logf(format string, args ...any) { fmt.Fprintf(os.Stderr, "[disk-load] "+format+"\n", args...) }
|
|
|
|
func main() {
|
|
// Readable: restic, nfs-server, mounts and the self-check read it (their manifests' `reads`); checks/readable holds it.
|
|
if err := stdio.Keeps(announce.State{Name: StateReadings, Readable: true}); err != nil {
|
|
logf("%v", err)
|
|
os.Exit(1)
|
|
}
|
|
node := os.Getenv("MESH_NODE")
|
|
k := &Keeper{Node: node, Store: busStore{}, Say: logf, Measurer: Measurer{Run: RootRunner, Now: time.Now},
|
|
Items: func(ctx context.Context) (map[string][]catalogue.PlacedDataItem, error) {
|
|
return placedItems(ctx, node)
|
|
}}
|
|
if node != "" {
|
|
every := time.Hour
|
|
if d, err := time.ParseDuration(os.Getenv("MESH_DISK_MEASURE_EVERY")); err == nil && d >= time.Minute {
|
|
every = d
|
|
}
|
|
go k.Loop(context.Background(), every, 3*time.Minute)
|
|
}
|
|
tools := append(Tools(Here()), ReadingTools(k)...)
|
|
// An empty name serves as the module the runtime names (MESH_SERVED_MODULE): disk-load.
|
|
if err := stdio.Serve("", tools); err != nil {
|
|
fmt.Fprintln(os.Stderr, err)
|
|
os.Exit(1)
|
|
}
|
|
}
|
|
|
|
// placedItems is every data item the modules placed on node declare, composed from the bus as the node composes itself.
|
|
func placedItems(ctx context.Context, node string) (map[string][]catalogue.PlacedDataItem, error) {
|
|
items, unplaced, err := frombus.DataItems(ctx, fromruntime.Reader(), frombus.Mesh{}, frombus.Scope{Node: node})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if len(unplaced) > 0 {
|
|
logf("data items left out as not placeable: %s", strings.Join(unplaced, "; "))
|
|
}
|
|
return items, nil
|
|
}
|